facturas 0.20.2 → 0.20.4
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/{chunk-3NOKGXXX.mjs → chunk-6U4NRHFP.mjs} +6 -4
- package/dist/{chunk-3NOKGXXX.mjs.map → chunk-6U4NRHFP.mjs.map} +1 -1
- package/dist/{chunk-XTKZ5FDN.mjs → chunk-B2M64SIK.mjs} +2 -15
- package/dist/chunk-B2M64SIK.mjs.map +1 -0
- package/dist/{chunk-ZNMTFZ2Q.mjs → chunk-CYXS3F34.mjs} +36 -23
- package/dist/chunk-CYXS3F34.mjs.map +1 -0
- package/dist/chunk-KDLY2XJO.mjs +19 -0
- package/dist/chunk-KDLY2XJO.mjs.map +1 -0
- package/dist/{chunk-JP3LVU7K.mjs → chunk-UOIZQMA6.mjs} +15 -7
- package/dist/chunk-UOIZQMA6.mjs.map +1 -0
- package/dist/{chunk-VF3XJXBG.mjs → chunk-WG6TAMBB.mjs} +6 -4
- package/dist/{chunk-VF3XJXBG.mjs.map → chunk-WG6TAMBB.mjs.map} +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.mjs +41 -32
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-BIkLOgBA.d.ts → client-BgWH_jKT.d.ts} +10 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +6 -5
- package/dist/index.mjs.map +1 -1
- package/dist/padron.mjs +2 -1
- package/dist/wsfe.mjs +3 -2
- package/dist/wsmtxca.mjs +3 -2
- package/package.json +1 -1
- package/dist/chunk-JP3LVU7K.mjs.map +0 -1
- package/dist/chunk-XTKZ5FDN.mjs.map +0 -1
- package/dist/chunk-ZNMTFZ2Q.mjs.map +0 -1
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/main.ts","../src/cli/cert.ts","../src/cli/csr.ts","../src/cli/discover.ts","../src/cli/output.ts","../src/cli/prompt.ts","../src/cli/check.ts","../src/cli/cuit.ts","../src/cli/arca-steps.ts","../src/cli/diagnose.ts","../src/cli/clipboard.ts","../src/cli/version.ts","../src/cli/help.ts","../src/cli/init.ts","../src/cli/issue.ts"],"sourcesContent":["import { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type ParseArgsConfig, parseArgs } from \"node:util\";\nimport { createArcaClient } from \"../client\";\nimport type { ArcaClientConfig } from \"../internal/types\";\nimport { createWsaaAuthModule } from \"../wsaa\";\nimport { type CertFlags, runCert } from \"./cert\";\nimport {\n type CheckFlags,\n describeSalesPointProblem,\n parseSalesPoint,\n runCheck,\n} from \"./check\";\nimport { copyToClipboard } from \"./clipboard\";\nimport { describeUnknownError } from \"./diagnose\";\nimport { type CliHelpTopic, renderHelp } from \"./help\";\nimport { type InitFlags, runInit } from \"./init\";\nimport { type IssueFlags, runIssue } from \"./issue\";\nimport {\n CLI_EXIT,\n type CliIo,\n type CliOutputStream,\n createWriter,\n shouldUseColor,\n} from \"./output\";\nimport { readCliVersion } from \"./version\";\n\nconst COMMANDS = [\"init\", \"cert\", \"check\", \"issue\"] as const;\ntype Command = (typeof COMMANDS)[number];\n\ntype OptionConfig = NonNullable<ParseArgsConfig[\"options\"]>;\n\nconst GLOBAL_OPTIONS: OptionConfig = {\n help: { type: \"boolean\", short: \"h\" },\n version: { type: \"boolean\", short: \"v\" },\n json: { type: \"boolean\" },\n \"no-color\": { type: \"boolean\" },\n};\n\nconst COMMAND_OPTIONS: Record<Command, OptionConfig> = {\n init: {\n ...GLOBAL_OPTIONS,\n cuit: { type: \"string\" },\n env: { type: \"string\" },\n name: { type: \"string\" },\n org: { type: \"string\" },\n dir: { type: \"string\" },\n force: { type: \"boolean\" },\n \"no-clipboard\": { type: \"boolean\" },\n \"no-paste\": { type: \"boolean\" },\n },\n cert: {\n ...GLOBAL_OPTIONS,\n env: { type: \"string\" },\n dir: { type: \"string\" },\n force: { type: \"boolean\" },\n },\n check: {\n ...GLOBAL_OPTIONS,\n cert: { type: \"string\" },\n key: { type: \"string\" },\n cuit: { type: \"string\" },\n env: { type: \"string\" },\n dir: { type: \"string\" },\n \"sales-point\": { type: \"string\" },\n \"no-cache\": { type: \"boolean\" },\n },\n issue: {\n ...GLOBAL_OPTIONS,\n cert: { type: \"string\" },\n key: { type: \"string\" },\n cuit: { type: \"string\" },\n env: { type: \"string\" },\n dir: { type: \"string\" },\n \"sales-point\": { type: \"string\" },\n \"no-cache\": { type: \"boolean\" },\n issuer: { type: \"string\" },\n },\n};\n\n/** Runs one CLI invocation and returns its exit code. Never calls `exit`. */\nexport async function run(argv: readonly string[], io: CliIo): Promise<number> {\n const command = argv.find((token) => !token.startsWith(\"-\"));\n const wantsHelp = argv.includes(\"--help\") || argv.includes(\"-h\");\n const wantsVersion = argv.includes(\"--version\") || argv.includes(\"-v\");\n const noColor = argv.includes(\"--no-color\");\n const help = (stream: CliOutputStream, topic: CliHelpTopic) =>\n renderHelp(topic, {\n color: shouldUseColor(stream, io.env, noColor),\n });\n\n if (wantsVersion) {\n io.stdout.write(`${readCliVersion()}\\n`);\n return CLI_EXIT.ok;\n }\n // `--help` never reaches ARCA, the filesystem or a prompt: it is the one\n // command that always works, even with the rest of the line malformed.\n if (wantsHelp) {\n io.stdout.write(help(io.stdout, isCommand(command) ? command : \"root\"));\n return CLI_EXIT.ok;\n }\n if (command === undefined) {\n io.stderr.write(help(io.stderr, \"root\"));\n return CLI_EXIT.usage;\n }\n if (!isCommand(command)) {\n io.stderr.write(\n `Comando desconocido: ${command}\\n\\n${help(io.stderr, \"root\")}`\n );\n return CLI_EXIT.usage;\n }\n\n let values: Record<string, string | boolean | undefined>;\n try {\n ({ values } = parseArgs({\n args: [...argv],\n options: COMMAND_OPTIONS[command],\n allowPositionals: true,\n strict: true,\n }) as { values: Record<string, string | boolean | undefined> });\n } catch (error) {\n io.stderr.write(\n `${describeParseError(error)}\\n\\n${help(io.stderr, command)}`\n );\n return CLI_EXIT.usage;\n }\n\n const json = values.json === true;\n const writer = createWriter(io.stdout, {\n color: shouldUseColor(io.stdout, io.env, noColor),\n });\n\n if (command === \"init\") {\n return await runInit(io, toInitFlags(values), writer);\n }\n if (command === \"cert\") {\n return await runCert(io, toCertFlags(values), writer);\n }\n\n const given = values[\"sales-point\"];\n const salesPoint =\n typeof given === \"string\" ? parseSalesPoint(given) : undefined;\n if (typeof given === \"string\" && salesPoint === undefined) {\n io.stderr.write(`${describeSalesPointProblem(given)}\\n`);\n return CLI_EXIT.usage;\n }\n\n const shared = toCheckFlags(values, salesPoint);\n if (command === \"check\") {\n return await runCheck(io, shared, writer, json);\n }\n return await runIssue(io, toIssueFlags(values, shared), writer, json);\n}\n\n/**\n * Entry point used by `bin/facturas.mjs`. Sets the process exit code. Nothing\n * reaches node's unhandled rejection handler from here: whatever a command\n * failed to catch comes out as the SDK's safe message, never a stack or a PEM.\n */\nexport async function main(\n argv: readonly string[] = process.argv.slice(2),\n io: CliIo = createDefaultIo()\n) {\n try {\n process.exitCode = await run(argv, io);\n } catch (error) {\n io.stderr.write(`${describeUnknownError(error).diagnosis}\\n`);\n process.exitCode = CLI_EXIT.failed;\n }\n}\n\n/** The real world: real streams, real env, the real SDK. */\nexport function createDefaultIo(): CliIo {\n return {\n stdout: process.stdout,\n stderr: process.stderr,\n stdin: process.stdin,\n env: process.env,\n cwd: process.cwd(),\n cacheDir: join(tmpdir(), \"facturas-cli\"),\n now: () => new Date(),\n copyToClipboard: (text) =>\n copyToClipboard(text, {\n env: process.env,\n platform: process.platform,\n }),\n createClient: (options) => createArcaClient(options),\n createAuth: (config: ArcaClientConfig) => createWsaaAuthModule({ config }),\n };\n}\n\n/** Node reports parse failures in English; the CLI only speaks castellano. */\nfunction describeParseError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n const unknownOption = /Unknown option '([^']+)'/.exec(message)?.[1];\n if (unknownOption !== undefined) {\n return `Opción desconocida: ${unknownOption}`;\n }\n const missingValue = /Option '([^']+)' argument missing/.exec(message)?.[1];\n if (missingValue !== undefined) {\n return `Falta el valor de ${missingValue}`;\n }\n return \"Argumentos inválidos.\";\n}\n\nfunction isCommand(value: string | undefined): value is Command {\n return COMMANDS.includes(value as Command);\n}\n\nfunction toInitFlags(\n values: Record<string, string | boolean | undefined>\n): InitFlags {\n return {\n ...text(values, \"cuit\", \"cuit\"),\n ...text(values, \"env\", \"env\"),\n ...text(values, \"name\", \"name\"),\n ...text(values, \"org\", \"org\"),\n ...text(values, \"dir\", \"dir\"),\n ...(values.force === true ? { force: true } : {}),\n ...(values[\"no-clipboard\"] === true ? { noClipboard: true } : {}),\n ...(values[\"no-paste\"] === true ? { noPaste: true } : {}),\n };\n}\n\nfunction toCertFlags(\n values: Record<string, string | boolean | undefined>\n): CertFlags {\n return {\n ...text(values, \"env\", \"env\"),\n ...text(values, \"dir\", \"dir\"),\n ...(values.force === true ? { force: true } : {}),\n };\n}\n\nfunction toCheckFlags(\n values: Record<string, string | boolean | undefined>,\n salesPoint: number | undefined\n): CheckFlags {\n return {\n ...text(values, \"cert\", \"cert\"),\n ...text(values, \"key\", \"key\"),\n ...text(values, \"cuit\", \"taxId\"),\n ...text(values, \"env\", \"env\"),\n ...text(values, \"dir\", \"dir\"),\n ...(salesPoint === undefined ? {} : { salesPoint }),\n ...(values[\"no-cache\"] === true ? { noCache: true } : {}),\n };\n}\n\nfunction toIssueFlags(\n values: Record<string, string | boolean | undefined>,\n shared: CheckFlags\n): IssueFlags {\n return { ...shared, ...text(values, \"issuer\", \"issuer\") };\n}\n\nfunction text<TKey extends string>(\n values: Record<string, string | boolean | undefined>,\n from: string,\n to: TKey\n): Partial<Record<TKey, string>> {\n const value = values[from];\n return typeof value === \"string\"\n ? ({ [to]: value } as Record<TKey, string>)\n : {};\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport type { ArcaEnvironment } from \"../internal/types\";\nimport {\n type CertificateFacts,\n privateKeyMatchesCertificate,\n readCertificateFacts,\n readCsrTaxId,\n} from \"./csr\";\nimport {\n certificateFileName,\n DISCOVERY_ORDER,\n privateKeyFileName,\n toEnvironment,\n} from \"./discover\";\nimport { CLI_EXIT, type CliIo, type CliWriter } from \"./output\";\nimport { askBlock, isInteractive } from \"./prompt\";\n\n/**\n * The certificate ARCA gives back, taken by paste. In homologación there is no\n * download —the PEM only exists in the browser— so the alternative to this is\n * the user opening an editor for a file they do not have yet.\n */\n\nconst BEGIN = \"-----BEGIN CERTIFICATE-----\";\nconst END = \"-----END CERTIFICATE-----\";\nconst PROMPT = \"> \";\n/** Three pastes before the CLI stops asking and says how to do it by hand. */\nconst PASTE_ATTEMPTS = 3;\nconst NOT_A_CERTIFICATE = [\n \"Eso no parece un certificado PEM. Tiene que ir de\",\n `${BEGIN} a ${END}.`,\n];\n\nexport type CertFlags = {\n env?: string;\n dir?: string;\n force?: boolean;\n};\n\n/** How a paste ended. Only `saved` wrote a file. */\nexport type PasteOutcome = \"saved\" | \"cancelled\" | \"exhausted\" | \"refused\";\n\nexport type PasteRequest = {\n /** What to say before the first prompt. Empty when there is no terminal. */\n intro: string[];\n certificatePath: string;\n certificateName: string;\n keyName: string;\n privateKeyPem: string;\n /** The CUIT the certificate has to be for, when the CLI knows it. */\n taxId?: string;\n};\n\n/**\n * Asks for the certificate, checks it against the key that is already on disk\n * and writes it. Refuses without writing when the certificate belongs to\n * another CUIT or to another key: both mean the paste came from the wrong tab,\n * and a saved file would fail later, in WSAA, with a worse message.\n */\nexport async function pasteCertificate(\n io: CliIo,\n writer: CliWriter,\n request: PasteRequest\n): Promise<PasteOutcome> {\n const interactive = isInteractive(io);\n if (request.intro.length > 0) {\n writer.blank();\n for (const line of request.intro) {\n writer.line(line);\n }\n writer.blank();\n }\n\n for (let attempt = 1; attempt <= PASTE_ATTEMPTS; attempt += 1) {\n // Sequential by nature: each try is an answer to the previous one.\n const lines = await askBlock(\n io,\n interactive ? PROMPT : \"\",\n (line) => line === END\n );\n if (lines === undefined) {\n return \"cancelled\";\n }\n\n const pem = toCertificatePem(lines);\n const facts = readFacts(pem);\n if (facts === undefined) {\n for (const line of NOT_A_CERTIFICATE) {\n io.stderr.write(`${line}\\n`);\n }\n if (interactive && attempt < PASTE_ATTEMPTS) {\n writer.blank();\n }\n continue;\n }\n\n const refusal = refuse(pem, facts, request);\n if (refusal !== undefined) {\n io.stderr.write(`${refusal}\\n`);\n return \"refused\";\n }\n\n writeFileSync(request.certificatePath, pem);\n writer.ok(\n request.certificateName,\n `certificado guardado, vence ${isoDate(facts.notAfter)}`\n );\n return \"saved\";\n }\n return \"exhausted\";\n}\n\n/** The line `init` and `cert` both print when nobody pasted anything. */\nexport function writeManualHint(\n writer: CliWriter,\n certificateName: string\n): void {\n writer.blank();\n writer.line(\n `Cuando tengas el certificado, guardalo acá como ${certificateName},`\n );\n writer.line(\"o pegalo con npx facturas cert, y corré:\");\n writer.blank();\n writer.command(\"npx facturas check\");\n}\n\n/** Reads the certificate that pairs with a key already in the directory. */\nexport async function runCert(\n io: CliIo,\n flags: CertFlags,\n writer: CliWriter\n): Promise<number> {\n const directory = isAbsolute(flags.dir ?? \"\")\n ? (flags.dir as string)\n : resolve(io.cwd, flags.dir ?? \".\");\n\n const asked = flags.env?.trim().toLowerCase();\n const environment =\n asked === undefined || asked === \"\" ? undefined : toEnvironment(asked);\n if (asked !== undefined && asked !== \"\" && environment === undefined) {\n io.stderr.write(\"Falta el entorno. Pasá --env test o --env production.\\n\");\n return CLI_EXIT.usage;\n }\n\n const found = findKeys(directory, environment);\n if (found.length > 1) {\n io.stderr.write(\n `Están ${found.map((candidate) => candidate.keyName).join(\" y \")} en este directorio\\n`\n );\n io.stderr.write(\n \"y no sé cuál querés. Elegí con --env test o --env production.\\n\"\n );\n return CLI_EXIT.failed;\n }\n\n const [target] = found;\n if (target === undefined) {\n const names = (environment === undefined ? DISCOVERY_ORDER : [environment])\n .map((candidate) => privateKeyFileName(candidate))\n .join(\" ni \");\n io.stderr.write(`No encontré ${names} en este directorio.\\n`);\n io.stderr.write(\"Generá la clave y el CSR con npx facturas init.\\n\");\n return CLI_EXIT.failed;\n }\n const certificatePath = resolve(directory, target.certificateName);\n if (existsSync(certificatePath) && flags.force !== true) {\n io.stderr.write(\n `Ya existe ${target.certificateName}. Usá --force para sobrescribir.\\n`\n );\n return CLI_EXIT.failed;\n }\n\n const taxId = readCsrTaxIdOf(directory, target.environment);\n const outcome = await pasteCertificate(io, writer, {\n intro: isInteractive(io)\n ? [\n \"Pegá el certificado que te dio ARCA. Termina solo al ver\",\n `${END}. Ctrl-C para salir.`,\n ]\n : [],\n certificatePath,\n certificateName: target.certificateName,\n keyName: target.keyName,\n privateKeyPem: readFileSync(resolve(directory, target.keyName), \"utf8\"),\n ...(taxId === undefined ? {} : { taxId }),\n });\n\n if (outcome === \"saved\") {\n writer.blank();\n writer.dim(\"Después:\");\n writer.blank();\n writer.command(\"npx facturas check\");\n return CLI_EXIT.ok;\n }\n if (outcome === \"cancelled\") {\n writer.blank();\n writer.line(\"Cuando lo tengas, volvé a correr npx facturas cert, o\");\n writer.line(`guardalo acá como ${target.certificateName}.`);\n return CLI_EXIT.ok;\n }\n if (outcome === \"exhausted\") {\n writeManualHint(writer, target.certificateName);\n }\n return CLI_EXIT.failed;\n}\n\ntype KeyCandidate = {\n environment: ArcaEnvironment;\n keyName: string;\n certificateName: string;\n};\n\n/** The keys `init` left in the directory, in the order `check` looks for them. */\nfunction findKeys(\n directory: string,\n environment: ArcaEnvironment | undefined\n): KeyCandidate[] {\n return (environment === undefined ? DISCOVERY_ORDER : [environment])\n .map((candidate) => ({\n environment: candidate,\n keyName: privateKeyFileName(candidate),\n certificateName: certificateFileName(candidate),\n }))\n .filter((candidate) => existsSync(resolve(directory, candidate.keyName)));\n}\n\n/** The CUIT of the CSR next to the key, when it is still there and readable. */\nfunction readCsrTaxIdOf(\n directory: string,\n environment: ArcaEnvironment\n): string | undefined {\n const path = resolve(directory, `arca-${environment}.csr`);\n if (!existsSync(path)) {\n return undefined;\n }\n try {\n return readCsrTaxId(readFileSync(path, \"utf8\"));\n } catch {\n return undefined;\n }\n}\n\n/** The pasted lines as a PEM file: nothing before BEGIN, one trailing newline. */\nfunction toCertificatePem(lines: string[]): string {\n const start = lines.indexOf(BEGIN);\n const body = start === -1 ? lines : lines.slice(start);\n return `${body.join(\"\\n\")}\\n`;\n}\n\nfunction readFacts(pem: string): CertificateFacts | undefined {\n try {\n return readCertificateFacts(pem);\n } catch {\n return undefined;\n }\n}\n\n/** Why this certificate cannot be saved next to this key, if it cannot. */\nfunction refuse(\n pem: string,\n facts: CertificateFacts,\n request: PasteRequest\n): string | undefined {\n if (\n request.taxId !== undefined &&\n facts.taxId !== undefined &&\n facts.taxId !== request.taxId\n ) {\n return `El certificado es de otro CUIT: ${facts.taxId}.`;\n }\n let matches: boolean;\n try {\n matches = privateKeyMatchesCertificate(pem, request.privateKeyPem);\n } catch {\n return `No pude leer ${request.keyName} como clave PEM.`;\n }\n return matches\n ? undefined\n : `El certificado no corresponde a ${request.keyName}. ¿Subiste otro CSR?`;\n}\n\nfunction isoDate(value: Date): string {\n return value.toISOString().slice(0, 10);\n}\n","import forge from \"node-forge\";\n\nconst RSA_MODULUS_BITS = 2048;\nconst RSA_PUBLIC_EXPONENT = 0x01_00_01;\n/** How ARCA writes the CUIT in the subject, with a literal space after `CUIT`. */\nconst SUBJECT_TAX_ID = /^CUIT\\s+(\\d{11})$/;\n\n/** The distinguished name ARCA expects on a certificate signing request. */\nexport type ArcaCsrSubject = {\n /** 11-digit CUIT. Goes to `serialNumber` as `CUIT <cuit>`. */\n taxId: string;\n /** Alias for the certificate. Goes to `CN`. */\n commonName: string;\n /** Organization. Goes to `O`; defaults to the CUIT when the caller has none. */\n organization: string;\n};\n\n/** An unencrypted PKCS#8 private key and the PKCS#10 request that pairs with it. */\nexport type ArcaCsrMaterial = {\n privateKeyPem: string;\n csrPem: string;\n};\n\n/** What a certificate says about itself, with no credential in sight. */\nexport type CertificateFacts = {\n notBefore: Date;\n notAfter: Date;\n /** The CUIT in `serialNumber`, when ARCA wrote one there. */\n taxId?: string;\n};\n\n/** Builds the subject in the order ARCA's manual writes it: C, O, CN, serialNumber. */\nexport function buildArcaCsrSubject(\n subject: ArcaCsrSubject\n): forge.pki.CertificateField[] {\n return [\n { name: \"countryName\", value: \"AR\" },\n { name: \"organizationName\", value: subject.organization },\n { name: \"commonName\", value: subject.commonName },\n { name: \"serialNumber\", value: `CUIT ${subject.taxId}` },\n ];\n}\n\n/** Generates an RSA 2048 key and the CSR to upload in ARCA. Pure and offline. */\nexport function createArcaCsrMaterial(\n subject: ArcaCsrSubject\n): ArcaCsrMaterial {\n const keyPair = forge.pki.rsa.generateKeyPair({\n bits: RSA_MODULUS_BITS,\n e: RSA_PUBLIC_EXPONENT,\n });\n const privateKeyPem = toPkcs8Pem(keyPair.privateKey);\n const request = forge.pki.createCertificationRequest();\n request.publicKey = keyPair.publicKey;\n request.setSubject(buildArcaCsrSubject(subject));\n request.sign(keyPair.privateKey, forge.md.sha256.create());\n\n return {\n privateKeyPem,\n csrPem: forge.pki.certificationRequestToPem(request),\n };\n}\n\n/** Serializes an RSA private key as an unencrypted PKCS#8 PEM. */\nexport function toPkcs8Pem(privateKey: forge.pki.rsa.PrivateKey): string {\n return forge.pki.privateKeyInfoToPem(\n forge.pki.wrapRsaPrivateKey(forge.pki.privateKeyToAsn1(privateKey))\n );\n}\n\n/**\n * Reads the validity window and the CUIT of a certificate PEM. Throws on\n * anything that is not a certificate. ARCA issues against the CSR this CLI\n * writes, so the CUIT comes back in `serialNumber` as `CUIT <11 dígitos>`;\n * a certificate from somewhere else may carry nothing there.\n */\nexport function readCertificateFacts(certificatePem: string): CertificateFacts {\n const certificate = forge.pki.certificateFromPem(certificatePem);\n const taxId = readSubjectTaxId(certificate);\n return {\n notBefore: certificate.validity.notBefore,\n notAfter: certificate.validity.notAfter,\n ...(taxId === undefined ? {} : { taxId }),\n };\n}\n\n/**\n * The CUIT in the subject of a certificate signing request. `init` writes it\n * there, so `cert` can read back which CUIT a directory belongs to without\n * asking. Throws on anything that is not a PKCS#10 request.\n */\nexport function readCsrTaxId(csrPem: string): string | undefined {\n return readSubjectTaxId(forge.pki.certificationRequestFromPem(csrPem));\n}\n\n/** Both a certificate and a request keep the CUIT in the same subject field. */\nfunction readSubjectTaxId(source: {\n subject: { getField(options: { name: string }): unknown };\n}): string | undefined {\n const field = source.subject.getField({ name: \"serialNumber\" }) as {\n value?: unknown;\n } | null;\n if (typeof field?.value !== \"string\") {\n return undefined;\n }\n return SUBJECT_TAX_ID.exec(field.value.trim())?.[1];\n}\n\n/**\n * True when the private key is the one the certificate was issued for: same\n * RSA modulus and same public exponent. Throws when either PEM does not parse.\n */\nexport function privateKeyMatchesCertificate(\n certificatePem: string,\n privateKeyPem: string\n): boolean {\n const certificate = forge.pki.certificateFromPem(certificatePem);\n const privateKey = forge.pki.privateKeyFromPem(privateKeyPem);\n const certificateKey = certificate.publicKey as forge.pki.rsa.PublicKey;\n\n if (certificateKey?.n === undefined || certificateKey.e === undefined) {\n return false;\n }\n\n return (\n certificateKey.n.compareTo(privateKey.n) === 0 &&\n certificateKey.e.compareTo(privateKey.e) === 0\n );\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { ARCA_ENVIRONMENTS } from \"../config\";\nimport type { ArcaEnvironment } from \"../internal/types\";\n\n/**\n * The credential files `init` writes, found where the user is standing. This\n * is a convenience of the CLI and nothing else: `createArcaClient()` keeps\n * reading the environment, and the SDK never looks at the filesystem.\n */\n\n/** Homologación first: it is where everyone starts. */\nexport const DISCOVERY_ORDER: readonly ArcaEnvironment[] = [\n \"test\",\n \"production\",\n];\n\n/** The environment a written answer names, or `undefined` when it names none. */\nexport function toEnvironment(value: string): ArcaEnvironment | undefined {\n return ARCA_ENVIRONMENTS.includes(value as ArcaEnvironment)\n ? (value as ArcaEnvironment)\n : undefined;\n}\n\n/** The certificate `init` tells the user to save for that environment. */\nexport function certificateFileName(environment: ArcaEnvironment): string {\n return `arca-${environment}.crt`;\n}\n\n/** The private key `init` writes for that environment. */\nexport function privateKeyFileName(environment: ArcaEnvironment): string {\n return `arca-${environment}.key`;\n}\n\n/** A complete pair, read from disk. */\nexport type DiscoveredCredentials = {\n environment: ArcaEnvironment;\n certificateFile: string;\n keyFile: string;\n certificatePem: string;\n privateKeyPem: string;\n};\n\n/**\n * What the directory holds. `ambiguous` means both environments are there and\n * only the user can say which one they meant; `incomplete` means half a pair,\n * which is what a directory looks like between `init` and ARCA's answer.\n */\nexport type CredentialDiscovery =\n | { kind: \"none\" }\n | { kind: \"found\"; credentials: DiscoveredCredentials }\n | { kind: \"ambiguous\"; files: string[] }\n | {\n kind: \"incomplete\";\n /** The file that is there, and the one that is not. */\n present: string;\n missing: string;\n /** Which half is missing, because the fix for each is different. */\n missingKind: \"certificate\" | \"key\";\n };\n\n/**\n * Looks for `arca-<entorno>.crt` and `arca-<entorno>.key` in one directory.\n * With an environment already chosen, only that pair is considered.\n *\n * @throws When a file exists but cannot be read.\n */\nexport function discoverCredentials(\n directory: string,\n environment?: ArcaEnvironment\n): CredentialDiscovery {\n const candidates = (\n environment === undefined ? DISCOVERY_ORDER : [environment]\n ).map((candidate) => {\n const certificateFile = certificateFileName(candidate);\n const keyFile = privateKeyFileName(candidate);\n return {\n environment: candidate,\n certificateFile,\n keyFile,\n hasCertificate: existsSync(resolve(directory, certificateFile)),\n hasKey: existsSync(resolve(directory, keyFile)),\n };\n });\n\n const complete = candidates.filter(\n (candidate) => candidate.hasCertificate && candidate.hasKey\n );\n if (complete.length > 1) {\n return {\n kind: \"ambiguous\",\n files: complete.map((candidate) => candidate.certificateFile),\n };\n }\n\n const [pair] = complete;\n if (pair !== undefined) {\n return {\n kind: \"found\",\n credentials: {\n environment: pair.environment,\n certificateFile: pair.certificateFile,\n keyFile: pair.keyFile,\n certificatePem: read(directory, pair.certificateFile),\n privateKeyPem: read(directory, pair.keyFile),\n },\n };\n }\n\n const half = candidates.find(\n (candidate) => candidate.hasCertificate || candidate.hasKey\n );\n if (half === undefined) {\n return { kind: \"none\" };\n }\n return half.hasCertificate\n ? {\n kind: \"incomplete\",\n present: half.certificateFile,\n missing: half.keyFile,\n missingKind: \"key\",\n }\n : {\n kind: \"incomplete\",\n present: half.keyFile,\n missing: half.certificateFile,\n missingKind: \"certificate\",\n };\n}\n\nfunction read(directory: string, file: string): string {\n return readFileSync(resolve(directory, file), \"utf8\").trim();\n}\n","import type { ArcaClient } from \"../client\";\nimport type { ArcaClientConfig, ArcaClientOptions } from \"../internal/types\";\nimport type { WsaaAuthModule } from \"../wsaa\";\n\n/** Minimal writable surface the CLI needs. Tests pass a string collector. */\nexport type CliOutputStream = {\n write(chunk: string): void;\n isTTY?: boolean;\n};\n\n/** Minimal readable surface the CLI needs for interactive prompts. */\nexport type CliInputStream = NodeJS.ReadableStream & { isTTY?: boolean };\n\n/** Everything the CLI touches outside itself. Injected so tests stay offline. */\nexport type CliIo = {\n stdout: CliOutputStream;\n stderr: CliOutputStream;\n stdin: CliInputStream;\n env: Record<string, string | undefined>;\n cwd: string;\n /** Where the WSAA ticket is cached between runs. Never holds anything else. */\n cacheDir: string;\n now(): Date;\n /**\n * Puts text in the system clipboard, answering whether it got there. Nothing\n * else in the CLI touches the clipboard, and a `false` is never an error.\n */\n copyToClipboard(text: string): Promise<boolean>;\n createClient(options: ArcaClientOptions): ArcaClient;\n createAuth(config: ArcaClientConfig): WsaaAuthModule;\n};\n\n/** 0 all good, 1 something ARCA-side is wrong, 2 the command was wrong. */\nexport const CLI_EXIT = {\n ok: 0,\n failed: 1,\n usage: 2,\n} as const;\n\nconst GREEN = \"\\u001B[32m\";\nconst RED = \"\\u001B[31m\";\nconst YELLOW = \"\\u001B[33m\";\nconst CYAN = \"\\u001B[36m\";\nconst BOLD = \"\\u001B[1m\";\nconst DIM = \"\\u001B[2m\";\nconst RESET = \"\\u001B[0m\";\n\n/** Column where a layer detail starts, so the marks line up like a shell. */\nconst LABEL_WIDTH = 22;\nconst INDENT = \" \";\n\n/**\n * Wraps text in one ANSI sequence, or returns it untouched when color is off.\n * The whole CLI paints through this, so `--no-color` output is the same text\n * minus the escapes and nothing else.\n */\nexport type CliPainter = {\n green(text: string): string;\n red(text: string): string;\n yellow(text: string): string;\n cyan(text: string): string;\n bold(text: string): string;\n dim(text: string): string;\n};\n\n/** The painter for a stream whose color was already decided. */\nexport function createPainter(color: boolean): CliPainter {\n const paint = (code: string) => (text: string) =>\n color ? `${code}${text}${RESET}` : text;\n return {\n green: paint(GREEN),\n red: paint(RED),\n yellow: paint(YELLOW),\n cyan: paint(CYAN),\n bold: paint(BOLD),\n dim: paint(DIM),\n };\n}\n\n/** One line per fact. Colors land on the mark and nowhere else. */\nexport type CliWriter = {\n /** The painter this writer prints with, for text painted before it gets here. */\n painter: CliPainter;\n ok(label: string, detail?: string): void;\n fail(label: string, detail?: string): void;\n warn(label: string, detail?: string): void;\n /** An indented continuation line: a diagnosis, a fix or one sales point. */\n note(text: string): void;\n line(text: string): void;\n /** A whole line in dim: an aside the reader can skip without losing the plot. */\n dim(text: string): void;\n /** An indented shell line: a dim `$` and the command in cyan. */\n command(text: string): void;\n blank(): void;\n json(value: unknown): void;\n};\n\n/**\n * ANSI is on only for a TTY without `NO_COLOR` and without `--no-color`.\n * Either of those two turns it off, whatever else says. `FORCE_COLOR` turns it\n * on without a TTY, for CI logs that do render escapes; `FORCE_COLOR=0` is the\n * conventional way of saying no.\n */\nexport function shouldUseColor(\n stream: CliOutputStream,\n env: Record<string, string | undefined>,\n noColorFlag = false\n): boolean {\n if (noColorFlag || env.NO_COLOR !== undefined) {\n return false;\n }\n if (env.FORCE_COLOR !== undefined) {\n return env.FORCE_COLOR !== \"0\";\n }\n return stream.isTTY === true;\n}\n\nexport function createWriter(\n stream: CliOutputStream,\n options: { color: boolean }\n): CliWriter {\n const painter = createPainter(options.color);\n\n const mark = (symbol: string, label: string, detail?: string) => {\n const body =\n detail === undefined ? label : `${label.padEnd(LABEL_WIDTH)} ${detail}`;\n stream.write(`${symbol} ${body}\\n`);\n };\n\n return {\n painter,\n ok(label, detail) {\n mark(painter.green(\"✓\"), label, detail);\n },\n fail(label, detail) {\n mark(painter.red(\"✗\"), label, detail);\n },\n warn(label, detail) {\n mark(painter.yellow(\"!\"), label, detail);\n },\n note(text) {\n stream.write(`${INDENT}${text}\\n`);\n },\n line(text) {\n stream.write(`${text}\\n`);\n },\n dim(text) {\n stream.write(`${painter.dim(text)}\\n`);\n },\n command(text) {\n stream.write(`${INDENT}${painter.dim(\"$\")} ${painter.cyan(text)}\\n`);\n },\n blank() {\n stream.write(\"\\n\");\n },\n json(value) {\n stream.write(`${JSON.stringify(value, null, 2)}\\n`);\n },\n };\n}\n","import { createInterface } from \"node:readline/promises\";\nimport type { CliIo } from \"./output\";\n\n/**\n * True when the CLI may ask a question. Without a TTY on stdin every missing\n * value has to arrive as a flag, so scripts and CI fail fast instead of hanging.\n */\nexport function isInteractive(io: CliIo): boolean {\n return io.stdin.isTTY === true;\n}\n\n/** Asks one question and returns the trimmed answer. Only call on a TTY. */\nexport async function ask(io: CliIo, question: string): Promise<string> {\n const rl = createInterface({\n input: io.stdin,\n output: io.stdout as NodeJS.WritableStream,\n });\n try {\n const answer = await rl.question(question);\n return answer.trim();\n } finally {\n rl.close();\n }\n}\n\n/**\n * Reads a pasted block: every line from the first non-blank one up to the one\n * `endsAt` recognizes, trimmed. `undefined` means the user backed out —Ctrl-C\n * on a terminal, or the end of the input anywhere else— and never a half block\n * the caller could mistake for a complete one.\n */\nexport async function askBlock(\n io: CliIo,\n prompt: string,\n endsAt: (line: string) => boolean\n): Promise<string[] | undefined> {\n io.stdout.write(prompt);\n const rl = createInterface({\n input: io.stdin,\n output: io.stdout as NodeJS.WritableStream,\n });\n const lines: string[] = [];\n let complete = false;\n // Without this listener readline lets Ctrl-C kill the process; with it, the\n // paste the user gave up on is just an empty answer.\n rl.on(\"SIGINT\", () => rl.close());\n try {\n for await (const raw of rl) {\n const line = raw.trim();\n if (lines.length === 0 && line === \"\") {\n continue;\n }\n lines.push(line);\n if (endsAt(line)) {\n complete = true;\n break;\n }\n }\n } finally {\n rl.close();\n }\n return complete ? lines : undefined;\n}\n","import { readFileSync } from \"node:fs\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport type { ArcaClient } from \"../client\";\nimport {\n ARCA_WSAA_CONFIG,\n assertArcaClientConfig,\n discoverArcaClientConfig,\n} from \"../config\";\nimport {\n ArcaConfigurationError,\n ArcaServiceError,\n ArcaSoapFaultError,\n isArcaAuthenticationError,\n} from \"../errors\";\nimport type {\n ArcaAuthCredentials,\n ArcaClientConfig,\n ArcaEnvironment,\n ArcaWsaaSessionStore,\n} from \"../internal/types\";\nimport type { WsfeSalesPoint } from \"../services/wsfe\";\nimport { createFileStore } from \"../store/file\";\nimport { createWsaaStoreAdapter } from \"../wsaa/store-adapter\";\nimport { privateKeyMatchesCertificate, readCertificateFacts } from \"./csr\";\nimport { describeTaxIdProblem, normalizeTaxId, TAX_ID_FIX } from \"./cuit\";\nimport {\n type CliDiagnosis,\n describeUnknownError,\n diagnose,\n diagnoseAuthenticationReason,\n diagnoseWsaaFaultCode,\n findSoapFault,\n findTransportError,\n} from \"./diagnose\";\nimport {\n type CredentialDiscovery,\n type DiscoveredCredentials,\n discoverCredentials,\n} from \"./discover\";\nimport { CLI_EXIT, type CliIo, type CliWriter } from \"./output\";\n\nconst EXPIRY_WARNING_DAYS = 30;\nconst EMPTY_IN_TEST_WARNING =\n \"en homologación ARCA suele no informarlos; probá igual con issue\";\nconst MILLISECONDS_PER_DAY = 86_400_000;\n\n/** The five layers, in the order ARCA breaks them. */\nexport type CliLayerName =\n | \"config\"\n | \"certificate\"\n | \"wsaa\"\n | \"wsfe\"\n | \"salesPoints\";\n\nconst LAYER_LABELS: Record<CliLayerName, string> = {\n config: \"configuración\",\n certificate: \"certificado y clave\",\n wsaa: \"WSAA\",\n wsfe: \"WSFE\",\n salesPoints: \"puntos de venta\",\n};\n\nexport type CliLayerReport = {\n name: CliLayerName;\n ok: boolean;\n detail?: string;\n expiresAt?: string;\n code?: string;\n reason?: string;\n diagnosis?: string;\n fix?: string;\n warning?: string;\n};\n\nexport type CliSalesPointReport = {\n number: number;\n blocked: boolean;\n system?: string;\n};\n\n/** The whole `check` result. Layers never reached are absent, not false. */\nexport type CliCheckReport = {\n ok: boolean;\n environment?: ArcaEnvironment;\n taxId?: string;\n layers: CliLayerReport[];\n salesPoints?: CliSalesPointReport[];\n};\n\nexport type CheckFlags = {\n cert?: string;\n key?: string;\n taxId?: string;\n env?: string;\n /** Where to look for `arca-<entorno>.crt` and `.key`. Defaults to the cwd. */\n dir?: string;\n salesPoint?: number;\n /** Skips the ticket cache: one forced login, kept in memory only. */\n noCache?: boolean;\n};\n\n/**\n * WSFE's `PtoVta` is an integer from 1 to 99999. Anything a number only starts\n * with —`3foo`, `3.5`, `1e2`— is a typo, not a sales point: parsing it would\n * silently work on a different one than the person typed.\n */\nconst SALES_POINT_MIN = 1;\nconst SALES_POINT_MAX = 99_999;\n\n/** The sales point a string names, or `undefined` when it names none. */\nexport function parseSalesPoint(value: string): number | undefined {\n if (!/^\\d+$/.test(value)) {\n return undefined;\n }\n const parsed = Number(value);\n return parsed >= SALES_POINT_MIN && parsed <= SALES_POINT_MAX\n ? parsed\n : undefined;\n}\n\n/** Why that string is not a sales point, in the words the CLI uses. */\nexport function describeSalesPointProblem(value: string): string {\n const reason = /^\\d+$/.test(value)\n ? `Tiene que estar entre ${SALES_POINT_MIN} y ${SALES_POINT_MAX}`\n : \"Tiene que ser un número entero\";\n return `Punto de venta inválido: ${value}. ${reason}, por ejemplo --sales-point 3.`;\n}\n\ntype TicketCache = {\n sessionStore: ArcaWsaaSessionStore;\n /** True once a stored ticket was handed back instead of a fresh login. */\n wasReused(): boolean;\n};\n\n/** The report plus the client the passing layers built, for `issue` to reuse. */\nexport type CliCheckResult = {\n report: CliCheckReport;\n client?: ArcaClient;\n};\n\n/** Runs `check` and prints it. Never writes to ARCA. */\nexport async function runCheck(\n io: CliIo,\n flags: CheckFlags,\n writer: CliWriter,\n json: boolean\n): Promise<number> {\n const { report } = await runCheckLayers(io, flags);\n if (json) {\n writer.json(report);\n } else {\n writeCheckReport(writer, report);\n }\n return report.ok ? CLI_EXIT.ok : CLI_EXIT.failed;\n}\n\n/** Runs the layers in order and stops at the first failure. */\nexport async function runCheckLayers(\n io: CliIo,\n flags: CheckFlags\n): Promise<CliCheckResult> {\n const layers: CliLayerReport[] = [];\n const resolved = resolveConfigLayer(io, flags);\n layers.push(resolved.layer);\n if (!(resolved.layer.ok && resolved.config)) {\n return { report: { ok: false, layers } };\n }\n\n const config = resolved.config;\n const report: CliCheckReport = {\n ok: false,\n environment: config.environment,\n taxId: config.taxId,\n layers,\n };\n\n const certificate = checkCertificate(config, io.now());\n layers.push(certificate);\n if (!certificate.ok) {\n return { report };\n }\n\n const cache =\n flags.noCache === true ? undefined : createTicketCache(io.cacheDir, config);\n const wsaa = await checkWsaa(io, config, cache);\n layers.push(wsaa.layer);\n if (!(wsaa.layer.ok && wsaa.credentials)) {\n return { report };\n }\n\n // WSFE reuses the ticket layer 3 obtained: a second login would collide with\n // it as coe.alreadyAuthenticated.\n const client = io.createClient({\n ...config,\n wsaaSessionStore:\n cache?.sessionStore ?? createEphemeralSessionStore(wsaa.credentials),\n });\n const wsfe = await checkWsfe(client);\n layers.push(wsfe.layer);\n if (!wsfe.layer.ok) {\n return { report, client };\n }\n\n const salesPoints = wsfe.salesPoints ?? [];\n report.salesPoints = salesPoints.map(toSalesPointReport);\n const layer = checkSalesPoints(\n report.salesPoints,\n config.environment,\n flags.salesPoint\n );\n layers.push(layer);\n report.ok = layer.ok;\n return { report, client };\n}\n\n/** Renders the report the way a shell would: one line per fact. */\nexport function writeCheckReport(\n writer: CliWriter,\n report: CliCheckReport\n): void {\n for (const layer of report.layers) {\n const label = LAYER_LABELS[layer.name];\n if (layer.ok) {\n writer.ok(label, layer.detail);\n } else {\n writer.fail(label);\n if (layer.diagnosis !== undefined) {\n writer.note(layer.diagnosis);\n }\n if (layer.fix !== undefined) {\n writer.note(layer.fix);\n }\n }\n if (layer.name === \"salesPoints\") {\n for (const point of report.salesPoints ?? []) {\n writer.note(describeSalesPoint(point));\n }\n }\n if (layer.warning !== undefined) {\n writer.warn(label, layer.warning);\n }\n }\n}\n\n/**\n * The environment `check` would use, found without touching ARCA: the flag,\n * the variable, or the name of the pair sitting in the directory. `issue` asks\n * first, because it refuses to write anywhere but homologación. `undefined`\n * means nothing said so yet; the layers will name whatever is wrong.\n */\nexport function resolveCheckEnvironment(\n io: CliIo,\n flags: CheckFlags\n): string | undefined {\n const chosen =\n flags.env?.trim().toLowerCase() || io.env.ARCA_ENVIRONMENT?.trim();\n if (chosen) {\n return chosen;\n }\n if (flags.cert?.trim() || io.env.ARCA_CERTIFICATE_PEM?.trim()) {\n return undefined;\n }\n try {\n const discovery = discoverCredentials(resolveDirectory(io, flags.dir));\n return discovery.kind === \"found\"\n ? discovery.credentials.environment\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Where every value came from. Flags win, then the environment variables, then\n * the files `init` left in the directory. The parts the line does not need are\n * absent: when the environment comes from the file name, saying it twice adds\n * nothing.\n */\ntype ConfigOrigin = {\n credentials?: string;\n taxId: string;\n environment?: string;\n};\n\nfunction resolveConfigLayer(\n io: CliIo,\n flags: CheckFlags\n): { layer: CliLayerReport; config?: ArcaClientConfig } {\n const chosenEnvironment =\n flags.env?.trim().toLowerCase() || io.env.ARCA_ENVIRONMENT?.trim();\n\n let certificatePem: string | undefined;\n let privateKeyPem: string | undefined;\n let discovery: CredentialDiscovery = { kind: \"none\" };\n try {\n certificatePem = readPem(io, flags.cert, io.env.ARCA_CERTIFICATE_PEM);\n privateKeyPem = readPem(io, flags.key, io.env.ARCA_PRIVATE_KEY_PEM);\n if (!(certificatePem && privateKeyPem)) {\n discovery = discoverCredentials(\n resolveDirectory(io, flags.dir),\n toEnvironment(chosenEnvironment)\n );\n }\n } catch (error) {\n const unknown = describeUnknownError(error);\n return {\n layer: failedLayer(\n \"config\",\n { diagnosis: unknown.diagnosis },\n unknown.code\n ),\n };\n }\n\n const failure = describeDiscoveryFailure(discovery);\n if (failure) {\n return { layer: failedLayer(\"config\", failure) };\n }\n\n const found = discovery.kind === \"found\" ? discovery.credentials : undefined;\n const certificate = certificatePem || found?.certificatePem;\n const privateKey = privateKeyPem || found?.privateKeyPem;\n\n const taxId = resolveTaxId(io, flags, certificate);\n if (\"layer\" in taxId) {\n return { layer: taxId.layer };\n }\n\n const environment = chosenEnvironment || found?.environment;\n if (!environment) {\n return { layer: failedLayer(\"config\", diagnose(\"config.environment\")) };\n }\n if (!(certificate && privateKey)) {\n return { layer: failedLayer(\"config\", diagnose(\"config.pem\")) };\n }\n\n try {\n const config = discoverArcaClientConfig({\n taxId: taxId.taxId,\n certificatePem: certificate,\n privateKeyPem: privateKey,\n environment: environment as ArcaEnvironment,\n });\n assertArcaClientConfig(config);\n return {\n layer: {\n name: \"config\",\n ok: true,\n detail: describeSources({\n ...describeCredentialSource(flags, found),\n taxId: taxId.source,\n ...describeEnvironmentSource(io, flags, config.environment),\n }),\n },\n config,\n };\n } catch (error) {\n return { layer: failedLayer(\"config\", toConfigDiagnosis(error)) };\n }\n}\n\n/**\n * The CUIT, in order: the flag, the variable, and last the `serialNumber` ARCA\n * wrote in the certificate. Without any of the three there is nothing to ask\n * ARCA about.\n */\nfunction resolveTaxId(\n io: CliIo,\n flags: CheckFlags,\n certificatePem: string | undefined\n): { taxId: string; source: string } | { layer: CliLayerReport } {\n const given = flags.taxId?.trim() || io.env.ARCA_TAX_ID?.trim();\n if (given) {\n const problem = describeTaxIdProblem(given);\n if (problem !== undefined) {\n return {\n layer: failedLayer(\"config\", { diagnosis: problem, fix: TAX_ID_FIX }),\n };\n }\n return {\n taxId: normalizeTaxId(given),\n source: flags.taxId?.trim() ? \"--cuit\" : \"ARCA_TAX_ID\",\n };\n }\n if (certificatePem === undefined) {\n return { layer: failedLayer(\"config\", diagnose(\"config.taxId\")) };\n }\n\n const fromCertificate = readCertificateTaxId(certificatePem);\n if (fromCertificate === undefined) {\n return { layer: failedLayer(\"config\", diagnose(\"config.taxIdUnknown\")) };\n }\n return {\n taxId: fromCertificate,\n source: `CUIT ${fromCertificate} del certificado`,\n };\n}\n\n/** The CUIT in the certificate, or nothing when the PEM does not even parse. */\nfunction readCertificateTaxId(certificatePem: string): string | undefined {\n try {\n return readCertificateFacts(certificatePem).taxId;\n } catch {\n // Layer 2 is where a PEM that does not parse gets its own row.\n return undefined;\n }\n}\n\nfunction describeDiscoveryFailure(\n discovery: CredentialDiscovery\n): CliDiagnosis | undefined {\n if (discovery.kind === \"ambiguous\") {\n return diagnose(\"config.files.ambiguous\", {\n files: discovery.files.join(\" y \"),\n });\n }\n if (discovery.kind === \"incomplete\") {\n return diagnose(\n discovery.missingKind === \"certificate\"\n ? \"config.files.missingCertificate\"\n : \"config.files.missingKey\",\n { file: discovery.present, missingFile: discovery.missing }\n );\n }\n return undefined;\n}\n\nfunction resolveDirectory(io: CliIo, directory: string | undefined): string {\n return isAbsolute(directory ?? \"\")\n ? (directory as string)\n : resolve(io.cwd, directory ?? \".\");\n}\n\nfunction toEnvironment(value: string | undefined): ArcaEnvironment | undefined {\n return value === \"test\" || value === \"production\" ? value : undefined;\n}\n\nfunction readPem(\n io: CliIo,\n file: string | undefined,\n fromEnv: string | undefined\n): string | undefined {\n if (file === undefined || file === \"\") {\n return fromEnv?.trim() || undefined;\n }\n const path = isAbsolute(file) ? file : resolve(io.cwd, file);\n return readFileSync(path, \"utf8\").trim();\n}\n\n/**\n * Only a file is worth naming. PEMs that came from the environment are the\n * default and stay unsaid, which keeps the old line for the old setup.\n */\nfunction describeCredentialSource(\n flags: CheckFlags,\n found: DiscoveredCredentials | undefined\n): { credentials?: string } {\n if (found !== undefined) {\n return { credentials: `${found.certificateFile} en este directorio` };\n }\n const named = [\n ...(flags.cert?.trim() ? [\"--cert\"] : []),\n ...(flags.key?.trim() ? [\"--key\"] : []),\n ];\n return named.length === 0 ? {} : { credentials: named.join(\" y \") };\n}\n\n/** The file name already says the environment, so nothing is added for it. */\nfunction describeEnvironmentSource(\n io: CliIo,\n flags: CheckFlags,\n environment: ArcaEnvironment\n): { environment?: string } {\n if (flags.env?.trim()) {\n return { environment: `--env=${environment}` };\n }\n if (io.env.ARCA_ENVIRONMENT?.trim()) {\n return { environment: `ARCA_ENVIRONMENT=${environment}` };\n }\n return {};\n}\n\nfunction describeSources(origin: ConfigOrigin): string {\n return [origin.credentials, origin.taxId, origin.environment]\n .filter((part): part is string => part !== undefined)\n .join(\", \");\n}\n\nfunction toConfigDiagnosis(error: unknown): CliDiagnosis {\n if (!(error instanceof ArcaConfigurationError)) {\n return { diagnosis: describeUnknownError(error).diagnosis };\n }\n if (error.message.includes(\"taxId\")) {\n return diagnose(\"config.taxId\");\n }\n if (error.message.includes(\"environment\")) {\n return diagnose(\"config.environment\");\n }\n if (\n error.message.includes(\"certificatePem\") ||\n error.message.includes(\"privateKeyPem\") ||\n error.message.includes(\"Encrypted private keys\")\n ) {\n return diagnose(\"cert.invalid\");\n }\n return { diagnosis: error.message };\n}\n\nfunction checkCertificate(config: ArcaClientConfig, now: Date): CliLayerReport {\n let facts: ReturnType<typeof readCertificateFacts>;\n let matches: boolean;\n try {\n facts = readCertificateFacts(config.certificatePem);\n matches = privateKeyMatchesCertificate(\n config.certificatePem,\n config.privateKeyPem\n );\n } catch {\n return failedLayer(\"certificate\", diagnose(\"cert.invalid\"));\n }\n\n // A certificate for another CUIT is a misconfiguration, not something ARCA\n // forgives: WSAA answers for whoever the certificate belongs to.\n if (facts.taxId !== undefined && facts.taxId !== config.taxId) {\n return failedLayer(\n \"certificate\",\n diagnose(\"cert.taxIdMismatch\", {\n certificateTaxId: facts.taxId,\n taxId: config.taxId,\n })\n );\n }\n\n const expiresAt = toIsoDate(facts.notAfter);\n if (facts.notAfter.getTime() <= now.getTime()) {\n return failedLayer(\n \"certificate\",\n diagnose(\"cert.expired\", { date: expiresAt })\n );\n }\n if (!matches) {\n return failedLayer(\"certificate\", diagnose(\"cert.mismatch\"));\n }\n\n const daysLeft = Math.floor(\n (facts.notAfter.getTime() - now.getTime()) / MILLISECONDS_PER_DAY\n );\n return {\n name: \"certificate\",\n ok: true,\n detail: `coinciden, vence ${expiresAt}`,\n expiresAt,\n ...(daysLeft < EXPIRY_WARNING_DAYS\n ? { warning: `vence en ${daysLeft} ${daysLeft === 1 ? \"día\" : \"días\"}` }\n : {}),\n };\n}\n\nasync function checkWsaa(\n io: CliIo,\n config: ArcaClientConfig,\n cache: TicketCache | undefined\n): Promise<{ layer: CliLayerReport; credentials?: ArcaAuthCredentials }> {\n try {\n const auth = io.createAuth({\n ...config,\n ...(cache === undefined ? {} : { wsaaSessionStore: cache.sessionStore }),\n });\n const credentials = await auth.login(\"wsfe\", {\n forceRefresh: cache === undefined,\n });\n return {\n layer: {\n name: \"wsaa\",\n ok: true,\n detail:\n cache?.wasReused() === true ? \"ticket vigente\" : \"ticket obtenido\",\n },\n credentials,\n };\n } catch (error) {\n return { layer: toWsaaFailure(error, config.environment) };\n }\n}\n\nfunction toWsaaFailure(\n error: unknown,\n environment: ArcaEnvironment\n): CliLayerReport {\n const fault = findSoapFault(error);\n const key = diagnoseWsaaFaultCode(fault?.faultCode);\n if (key !== undefined) {\n return failedLayer(\"wsaa\", diagnose(key), fault?.code);\n }\n\n const transport = findTransportError(error);\n if (transport) {\n const host = new URL(ARCA_WSAA_CONFIG.endpoint[environment]).host;\n return failedLayer(\n \"wsaa\",\n diagnose(\"wsaa.transport\", { host }),\n transport.code\n );\n }\n\n const unknown = describeUnknownError(error);\n return failedLayer(\"wsaa\", { diagnosis: unknown.diagnosis }, unknown.code);\n}\n\nasync function checkWsfe(\n client: ArcaClient\n): Promise<{ layer: CliLayerReport; salesPoints?: WsfeSalesPoint[] }> {\n try {\n const status = await client.wsfe.getServerStatus();\n const down = [\n [\"appServer\", status.appServer],\n [\"dbServer\", status.dbServer],\n [\"authServer\", status.authServer],\n ].filter(([, value]) => value.toUpperCase() !== \"OK\");\n if (down.length > 0) {\n const message = down\n .map(([name, value]) => `${name}=${value}`)\n .join(\", \");\n return {\n layer: failedLayer(\"wsfe\", diagnose(\"wsfe.serviceError\", { message })),\n };\n }\n\n const salesPoints = await client.wsfe.getSalesPoints();\n return {\n layer: { name: \"wsfe\", ok: true, detail: \"servidor ok\" },\n salesPoints,\n };\n } catch (error) {\n return { layer: toWsfeFailure(error) };\n }\n}\n\nfunction toWsfeFailure(error: unknown): CliLayerReport {\n if (isArcaAuthenticationError(error)) {\n return {\n ...failedLayer(\n \"wsfe\",\n diagnoseAuthenticationReason(error.reason),\n error.code\n ),\n reason: error.reason,\n };\n }\n if (\n error instanceof ArcaServiceError ||\n error instanceof ArcaSoapFaultError\n ) {\n return failedLayer(\n \"wsfe\",\n diagnose(\"wsfe.serviceError\", { message: error.message }),\n error.code\n );\n }\n const unknown = describeUnknownError(error);\n return failedLayer(\"wsfe\", { diagnosis: unknown.diagnosis }, unknown.code);\n}\n\nfunction checkSalesPoints(\n points: CliSalesPointReport[],\n environment: ArcaEnvironment,\n requested: number | undefined\n): CliLayerReport {\n if (requested !== undefined) {\n const found = points.find((point) => point.number === requested);\n if (!found) {\n // Homologación often reports no points at all for ones that work.\n if (points.length === 0 && environment === \"test\") {\n return {\n name: \"salesPoints\",\n ok: true,\n detail: `${requested} (no informado)`,\n warning: EMPTY_IN_TEST_WARNING,\n };\n }\n return failedLayer(\n \"salesPoints\",\n diagnose(\"salesPoint.missing\", { salesPoint: requested })\n );\n }\n if (found.blocked) {\n return failedLayer(\n \"salesPoints\",\n diagnose(\"salesPoint.blocked\", { salesPoint: requested })\n );\n }\n return {\n name: \"salesPoints\",\n ok: true,\n detail: describeSalesPoint(found),\n };\n }\n\n if (points.length === 0) {\n // In homologación ARCA often reports nothing for points that work. In\n // production an empty list is the whole answer: no invoice can be issued.\n if (environment === \"test\") {\n return {\n name: \"salesPoints\",\n ok: true,\n detail: \"ninguno informado\",\n warning: EMPTY_IN_TEST_WARNING,\n };\n }\n return failedLayer(\"salesPoints\", diagnose(\"salesPoint.none\"));\n }\n\n return {\n name: \"salesPoints\",\n ok: true,\n detail: `${points.length} ${points.length === 1 ? \"informado\" : \"informados\"}`,\n };\n}\n\n/**\n * The WSAA ticket, kept in the system temp directory so `check` and `issue`\n * can be run again inside the 12 hours ARCA keeps it valid. The file store\n * creates the directory 0700 and writes 0600. Nothing else is ever stored.\n */\nfunction createTicketCache(\n directory: string,\n config: ArcaClientConfig\n): TicketCache {\n const store = createWsaaStoreAdapter(createFileStore(directory), config);\n let reused = false;\n const remove = store.delete?.bind(store);\n return {\n sessionStore: {\n get: async (key) => {\n const credentials = await store.get(key);\n if (credentials) {\n reused = true;\n }\n return credentials;\n },\n set: (key, credentials) => store.set(key, credentials),\n ...(remove === undefined ? {} : { delete: remove }),\n },\n wasReused: () => reused,\n };\n}\n\n/** Keeps the ticket from the WSAA layer in memory so WSFE reuses it. */\nfunction createEphemeralSessionStore(\n credentials: ArcaAuthCredentials\n): ArcaWsaaSessionStore {\n return {\n get: () => Promise.resolve(credentials),\n set: () => Promise.resolve(),\n };\n}\n\nfunction toSalesPointReport(point: WsfeSalesPoint): CliSalesPointReport {\n return {\n number: point.number,\n blocked: point.blocked,\n ...(point.emissionType === undefined ? {} : { system: point.emissionType }),\n };\n}\n\nfunction describeSalesPoint(point: CliSalesPointReport): string {\n const state = point.blocked ? \"bloqueado\" : \"habilitado\";\n return point.system === undefined\n ? `${point.number} (${state})`\n : `${point.number} (${state}, ${point.system})`;\n}\n\nfunction failedLayer(\n name: CliLayerName,\n row: CliDiagnosis,\n code?: string\n): CliLayerReport {\n return {\n name,\n ok: false,\n diagnosis: row.diagnosis,\n ...(row.fix === undefined ? {} : { fix: row.fix }),\n ...(code === undefined ? {} : { code }),\n };\n}\n\nfunction toIsoDate(value: Date): string {\n return value.toISOString().slice(0, 10);\n}\n","/**\n * CUIT validation for the CLI, so a wrong number is named as wrong instead of\n * being reported as missing. The SDK keeps its own, looser rule: it only asks\n * for eleven digits, and it is ARCA that decides whether a CUIT exists.\n */\n\n/** The weights ARCA applies to the first ten digits, in order. */\nconst CHECK_DIGIT_WEIGHTS = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2] as const;\nconst TAX_ID_LENGTH = 11;\nconst MODULUS = 11;\nconst SEPARATORS = /[\\s.-]/g;\n\n/** What to do about a CUIT the CLI rejected. One line, same everywhere. */\nexport const TAX_ID_FIX =\n \"Son 11 dígitos y el último es el verificador; podés escribirlo con guiones.\";\n\n/** Drops the separators people type: `20-12345678-6` and `20 12345678 6`. */\nexport function normalizeTaxId(raw: string): string {\n return raw.trim().replace(SEPARATORS, \"\");\n}\n\n/**\n * Why this CUIT cannot be used, or `undefined` when it is a well-formed one.\n * An empty value is reported as eleven digits missing; callers that can tell\n * \"missing\" from \"wrong\" should check for emptiness before calling.\n */\nexport function describeTaxIdProblem(raw: string): string | undefined {\n const digits = normalizeTaxId(raw);\n if (!/^\\d*$/.test(digits)) {\n return `CUIT inválido: ${raw.trim()} tiene caracteres que no son dígitos.`;\n }\n if (digits.length !== TAX_ID_LENGTH) {\n const plural = digits.length === 1 ? \"dígito\" : \"dígitos\";\n return `CUIT inválido: ${digits} tiene ${digits.length} ${plural} y necesita ${TAX_ID_LENGTH}.`;\n }\n if (!hasValidCheckDigit(digits)) {\n return `CUIT inválido: ${digits} no pasa el dígito verificador.`;\n }\n return undefined;\n}\n\n/** True when the CUIT is well formed. Says nothing about it existing in ARCA. */\nexport function isValidTaxId(raw: string): boolean {\n return describeTaxIdProblem(raw) === undefined;\n}\n\n/**\n * The módulo 11 rule ARCA uses: the first ten digits weighted by\n * `5 4 3 2 7 6 5 4 3 2`, and the check digit is `11 - (suma % 11)`. A\n * remainder of 0 leaves 11, which is written as 0. A remainder of 1 would\n * need a 10, which is not a digit: ARCA issues those numbers under another\n * prefix (23) instead, so no real CUIT has one.\n */\nfunction hasValidCheckDigit(digits: string): boolean {\n const sum = CHECK_DIGIT_WEIGHTS.reduce(\n (total, weight, index) => total + weight * Number(digits[index]),\n 0\n );\n const remainder = sum % MODULUS;\n if (remainder === 1) {\n return false;\n }\n const expected = remainder === 0 ? 0 : MODULUS - remainder;\n return expected === Number(digits[TAX_ID_LENGTH - 1]);\n}\n","import type { ArcaEnvironment } from \"../internal/types\";\nimport type { CliPainter } from \"./output\";\n\n/**\n * ARCA page, menu, field and button names, in one table so a rename is one\n * edit here and one in `docs/cli.md`. Verified against the official references\n * linked from `docs/habilitacion-arca.md`: the WSASS user manual\n * (`ws/WSASS/html/`), `WSASS_como_adherirse.pdf`, `WSAA.ObtenerCertificado.pdf`\n * and `ADMINREL.DelegarWS.pdf`.\n */\nexport const ARCA_PAGES = {\n login: \"https://auth.afip.gob.ar/contribuyente_/login.xhtml\",\n wsassService: \"WSASS - Autogestión Certificados Homologación\",\n wsassNewCertificate: \"Nuevo Certificado\",\n wsassNewCertificateButton: \"Crear DN y Obtener Certificado\",\n wsassAuthorizeService: \"Crear autorización a servicio\",\n wsassAuthorizeButton: \"Crear Autorización de Acceso\",\n wsassDnField: \"Nombre simbólico del DN\",\n wsassCsrField: \"Solicitud de certificado\",\n wsassAuthorizeDnField: \"Nombre simbólico del DN a autorizar\",\n wsassRepresentedField: \"CUIT representado\",\n wsassServiceField: \"Servicio al que desea acceder\",\n wsfeService: \"wsfe - Facturación Electrónica\",\n certificates: \"Administración de Certificados Digitales\",\n certificatesAddAlias: \"Agregar alias\",\n relationships: \"Administrador de Relaciones\",\n relationshipsNew: \"Nueva Relación\",\n relationshipsAdhere: \"Adherir Servicio\",\n relationshipsPath: \"Nueva Relación → Webservices → Facturación Electrónica\",\n salesPoints: \"Administración de Puntos de Venta y Domicilios\",\n salesPointsSystem: \"RECE para aplicativo y Web Services\",\n salesPointsSystemMonotributo:\n \"Factura Electrónica – Monotributo – Web Services\",\n} as const;\n\n/** One printed line of the plan. Every one of them is an instruction. */\nexport type ArcaPlanLine = { text: string };\n\n/** The whole block `init` prints after the files: a heading and its steps. */\nexport type ArcaPlan = { heading: string; lines: ArcaPlanLine[] };\n\n/** What the plan needs from the run: the alias and the file names in play. */\nexport type ArcaPlanContext = {\n alias: string;\n taxId: string;\n csrName: string;\n certificateName: string;\n /** True when the CSR is already in the clipboard and step 3 is one paste. */\n clipboard: boolean;\n /** The CSR itself, printed in step 3 when there is no clipboard. */\n csrPem: string;\n /** True when the CLI is about to ask for the certificate right below. */\n paste: boolean;\n};\n\nconst STEP_INDENT = \" \";\n/** Where a wrapped step line starts: under the step text, not under its number. */\nconst WRAP_INDENT = \" \";\nconst FIELD_INDENT = \" \";\n/** Spaces between the widest label of a step and its value column. */\nconst COLUMN_GAP = 3;\n\n/** One `label value` row, plus the block that hangs under it, if any. */\ntype Field = { label: string; value: string; lines?: string[] };\n\n/**\n * The ARCA steps for one environment, as a single linear list. `init` already\n * knows the environment, so the other one is noise: nothing here mentions it.\n */\nexport function buildArcaPlan(\n environment: ArcaEnvironment,\n context: ArcaPlanContext,\n painter: CliPainter\n): ArcaPlan {\n return environment === \"test\"\n ? buildTestPlan(context, painter)\n : buildProductionPlan(context, painter);\n}\n\nfunction buildTestPlan(\n context: ArcaPlanContext,\n painter: CliPainter\n): ArcaPlan {\n const name = (text: string) => painter.bold(`\"${text}\"`);\n return {\n heading: \"Listo. Ahora en ARCA, para homologación:\",\n lines: [\n ...step(1, [\"Entrá con clave fiscal en\", ARCA_PAGES.login]),\n ...step(2, [\n `Abrí ${name(ARCA_PAGES.wsassService)} en Mis Servicios.`,\n `Si no está, agregalo en ${ARCA_PAGES.relationships} → ${ARCA_PAGES.relationshipsAdhere}`,\n \"→ ARCA → Servicios Interactivos → WSASS, y volvé a entrar. Va con tu\",\n \"clave fiscal de persona física, nivel 2 o superior: no es delegable.\",\n ]),\n ...step(\n 3,\n [`En el menú, ${name(ARCA_PAGES.wsassNewCertificate)}:`],\n [\n { label: ARCA_PAGES.wsassDnField, value: context.alias },\n csrField(context),\n ],\n [`Apretá ${name(ARCA_PAGES.wsassNewCertificateButton)}.`]\n ),\n ...step(4, [\n \"El certificado sale en el cuadro de resultado, de\",\n \"-----BEGIN CERTIFICATE----- a -----END CERTIFICATE-----.\",\n context.paste\n ? \"Copialo entero y pegalo acá abajo.\"\n : `Copialo entero y guardalo acá como ${context.certificateName}.`,\n ]),\n ...step(\n 5,\n [`En el menú, ${name(ARCA_PAGES.wsassAuthorizeService)}:`],\n [\n { label: ARCA_PAGES.wsassAuthorizeDnField, value: context.alias },\n { label: ARCA_PAGES.wsassRepresentedField, value: context.taxId },\n {\n label: ARCA_PAGES.wsassServiceField,\n value: ARCA_PAGES.wsfeService,\n },\n ],\n [`Apretá ${name(ARCA_PAGES.wsassAuthorizeButton)}.`]\n ),\n ],\n };\n}\n\nfunction buildProductionPlan(\n context: ArcaPlanContext,\n painter: CliPainter\n): ArcaPlan {\n const name = (text: string) => painter.bold(`\"${text}\"`);\n return {\n heading: \"Listo. Ahora en ARCA, para producción:\",\n lines: [\n ...step(1, [\"Entrá con clave fiscal en\", ARCA_PAGES.login]),\n ...step(2, [\n `Abrí ${name(ARCA_PAGES.certificates)} en Mis Servicios.`,\n `Si no está, agregalo en ${ARCA_PAGES.relationships} → ${ARCA_PAGES.relationshipsNew}`,\n \"→ BUSCAR → Servicios Interactivos → Administración de Certificados\",\n \"Digitales → Confirmar, y volvé a entrar.\",\n ]),\n ...step(\n 3,\n [`Apretá ${name(ARCA_PAGES.certificatesAddAlias)}:`],\n [\n { label: \"Alias\", value: context.alias },\n { label: \"Seleccionar archivo\", value: context.csrName },\n ],\n [`Apretá ${name(ARCA_PAGES.certificatesAddAlias)} para subirlo.`]\n ),\n ...step(4, [\n `En la lista, entrá con ${name(\"Ver\")} y usá el icono ${name(\"Descargar\")}`,\n \"para bajar el certificado (archivo CRT).\",\n context.paste\n ? `Guardalo acá como ${context.certificateName}, o abrilo y pegalo abajo.`\n : `Guardalo acá como ${context.certificateName}.`,\n ]),\n ...step(\n 5,\n [\n `Volvé a ${ARCA_PAGES.relationships}, ${name(ARCA_PAGES.relationshipsNew)}:`,\n ],\n [\n {\n label: \"Servicio\",\n value: \"BUSCAR → Webservices → Facturación Electrónica\",\n },\n {\n label: \"Representante\",\n value: `BUSCAR → el computador fiscal ${context.alias}`,\n },\n ],\n [\n `Apretá ${name(\"Confirmar\")}, revisá y volvé a apretar ${name(\"Confirmar\")}.`,\n ]\n ),\n ],\n };\n}\n\n/**\n * One numbered step: its text, an optional aligned `label value` block and\n * the lines that come after it.\n */\nfunction step(\n number: number,\n text: string[],\n fields: Field[] = [],\n after: string[] = []\n): ArcaPlanLine[] {\n const [first, ...rest] = text;\n const lines: ArcaPlanLine[] = [{ text: `${STEP_INDENT}${number}. ${first}` }];\n for (const line of rest) {\n lines.push({ text: `${WRAP_INDENT}${line}` });\n }\n const width = columnWidth(fields);\n for (const field of fields) {\n const padding = \" \".repeat(width - field.label.length);\n lines.push({\n text: `${FIELD_INDENT}${field.label}:${padding}${field.value}`,\n });\n for (const line of field.lines ?? []) {\n lines.push({ text: `${FIELD_INDENT}${line}` });\n }\n }\n for (const line of after) {\n lines.push({ text: `${WRAP_INDENT}${line}` });\n }\n return lines;\n}\n\n/**\n * The CSR row of step 3. With the clipboard it is one word; without it the\n * whole request goes under the field, because a terminal is the only place\n * the user can copy it from without opening an editor.\n */\nfunction csrField(context: ArcaPlanContext): Field {\n if (context.clipboard) {\n return {\n label: ARCA_PAGES.wsassCsrField,\n value: \"pegá (ya está en tu portapapeles)\",\n };\n }\n return {\n label: ARCA_PAGES.wsassCsrField,\n value: \"copiá esto entero:\",\n lines: context.csrPem\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\"),\n };\n}\n\n/** Where the values start, counting the colon the labels get when printed. */\nfunction columnWidth(fields: Field[]): number {\n const widest = fields.reduce(\n (longest, field) => Math.max(longest, field.label.length),\n 0\n );\n return widest + COLUMN_GAP;\n}\n","import {\n type ArcaAuthenticationReason,\n ArcaSoapFaultError,\n ArcaTransportError,\n toArcaSafeErrorMetadata,\n} from \"../errors\";\nimport { ARCA_PAGES } from \"./arca-steps\";\n\n/** Keys of {@link CLI_DIAGNOSES}. One row of the published diagnosis table. */\nexport type CliDiagnosisKey =\n | \"config.taxId\"\n | \"config.taxIdUnknown\"\n | \"config.environment\"\n | \"config.pem\"\n | \"config.files.ambiguous\"\n | \"config.files.missingCertificate\"\n | \"config.files.missingKey\"\n | \"cert.invalid\"\n | \"cert.taxIdMismatch\"\n | \"cert.mismatch\"\n | \"cert.expired\"\n | \"wsaa.certExpired\"\n | \"wsaa.certUntrusted\"\n | \"wsaa.signInvalid\"\n | \"wsaa.notAuthorized\"\n | \"wsaa.alreadyAuthenticated\"\n | \"wsaa.clockSkew\"\n | \"wsaa.transport\"\n | \"wsfe.missing_relationship\"\n | \"wsfe.unauthorized_computer\"\n | \"wsfe.invalid_token\"\n | \"wsfe.authentication_rejected\"\n | \"wsfe.serviceError\"\n | \"salesPoint.missing\"\n | \"salesPoint.none\"\n | \"salesPoint.blocked\";\n\n/** What went wrong, and the page and action that fix it. Both in castellano. */\nexport type CliDiagnosis = {\n diagnosis: string;\n fix?: string;\n};\n\n/** Values substituted into the `{placeholders}` of a row. */\nexport type CliDiagnosisValues = {\n certificateTaxId?: string;\n date?: string;\n file?: string;\n files?: string;\n host?: string;\n message?: string;\n missingFile?: string;\n salesPoint?: number;\n taxId?: string;\n};\n\n/**\n * The diagnosis table. Every failure the CLI can name has exactly one row, and\n * every row is unit-tested. Nothing here interpolates a PEM, a token or a sign.\n */\nexport const CLI_DIAGNOSES: Record<CliDiagnosisKey, CliDiagnosis> = {\n \"config.taxId\": {\n diagnosis: \"Falta el CUIT.\",\n fix: \"export ARCA_TAX_ID=20123456786\",\n },\n \"config.taxIdUnknown\": {\n diagnosis: \"El certificado no dice de qué CUIT es.\",\n fix: \"Pasá --cuit 20123456786 o definí ARCA_TAX_ID.\",\n },\n \"config.environment\": {\n diagnosis: \"Falta el entorno.\",\n fix: \"export ARCA_ENVIRONMENT=test\",\n },\n \"config.pem\": {\n diagnosis: \"Falta el certificado o la clave.\",\n fix: \"Guardá arca-<entorno>.crt y arca-<entorno>.key acá, o pasá --cert y --key, o definí las variables ARCA_*_PEM.\",\n },\n \"config.files.ambiguous\": {\n diagnosis: \"Están {files} en este directorio y no sé cuál querés.\",\n fix: \"Elegí con --env test o --env production.\",\n },\n \"config.files.missingCertificate\": {\n diagnosis: \"Está {file} pero falta {missingFile}.\",\n fix: \"Descargá el certificado de ARCA y guardalo acá como {missingFile}.\",\n },\n \"config.files.missingKey\": {\n diagnosis: \"Está {file} pero falta {missingFile}.\",\n fix: \"Poné acá la clave con la que generaste el CSR, o pasá --key.\",\n },\n \"cert.invalid\": {\n diagnosis: \"El archivo no es un PEM válido.\",\n fix: \"Revisá que copiaste el bloque completo, con BEGIN y END.\",\n },\n \"cert.taxIdMismatch\": {\n diagnosis:\n \"El certificado es del CUIT {certificateTaxId} y el configurado es {taxId}.\",\n fix: \"Usá el certificado de ese CUIT, o corregí --cuit o ARCA_TAX_ID.\",\n },\n \"cert.mismatch\": {\n diagnosis: \"La clave privada no corresponde a este certificado.\",\n fix: \"Usá la clave con la que generaste el CSR (arca-<entorno>.key).\",\n },\n \"cert.expired\": {\n diagnosis: \"El certificado venció el {date}.\",\n fix: \"Generá un CSR nuevo con npx facturas init y renovalo en ARCA.\",\n },\n \"wsaa.certExpired\": {\n diagnosis: \"El certificado venció.\",\n fix: \"Generá un CSR nuevo con npx facturas init y renovalo en ARCA.\",\n },\n \"wsaa.certUntrusted\": {\n diagnosis: \"ARCA no reconoce este certificado en este entorno.\",\n fix: \"Homologación y producción tienen certificados propios; revisá ARCA_ENVIRONMENT.\",\n },\n \"wsaa.signInvalid\": {\n diagnosis: \"La firma del pedido no es válida.\",\n fix: \"La clave no corresponde al certificado, o el PEM está truncado.\",\n },\n \"wsaa.notAuthorized\": {\n diagnosis: \"El certificado no está autorizado para wsfe.\",\n fix: `${ARCA_PAGES.wsassService} → ${ARCA_PAGES.wsassAuthorizeService} (homologación) / ${ARCA_PAGES.relationships} (producción).`,\n },\n \"wsaa.alreadyAuthenticated\": {\n diagnosis: \"Ya hay un ticket vigente para este certificado.\",\n fix: \"Otro proceso o máquina tiene el ticket vigente. Esperá hasta 12 horas, o corré check desde donde lo pediste.\",\n },\n \"wsaa.clockSkew\": {\n diagnosis: \"La hora de tu máquina difiere de la de ARCA.\",\n fix: \"Sincronizá el reloj (NTP) y volvé a probar.\",\n },\n \"wsaa.transport\": {\n diagnosis: \"No se pudo conectar con {host}.\",\n fix: \"Revisá red, proxy o firewall; ARCA homologación suele caerse los fines de semana.\",\n },\n \"wsfe.missing_relationship\": {\n diagnosis:\n \"El certificado no tiene la relación con Facturación Electrónica.\",\n fix: `${ARCA_PAGES.relationships} → ${ARCA_PAGES.relationshipsPath}.`,\n },\n \"wsfe.unauthorized_computer\": {\n diagnosis: \"El certificado o computador no está autorizado.\",\n fix: \"Verificá que el alias esté asociado al servicio en este entorno.\",\n },\n \"wsfe.invalid_token\": {\n diagnosis: \"El ticket fue rechazado.\",\n fix: \"Volvé a ejecutar check; si persiste, revisá el reloj.\",\n },\n \"wsfe.authentication_rejected\": {\n diagnosis: \"ARCA denegó el acceso al servicio.\",\n fix: \"Revisá entorno y relación del certificado.\",\n },\n \"wsfe.serviceError\": {\n diagnosis: \"ARCA respondió con un error: {message}.\",\n },\n \"salesPoint.missing\": {\n diagnosis:\n \"El punto de venta {salesPoint} no está habilitado para web services.\",\n fix: `ARCA → ${ARCA_PAGES.salesPoints} → Nuevo → el sistema de web services de tu condición (\"${ARCA_PAGES.salesPointsSystem}\" para responsable inscripto).`,\n },\n \"salesPoint.none\": {\n diagnosis: \"ARCA no informa ningún punto de venta para web services.\",\n fix: `ARCA → ${ARCA_PAGES.salesPoints} → Nuevo → \"${ARCA_PAGES.salesPointsSystem}\" para responsable inscripto, \"${ARCA_PAGES.salesPointsSystemMonotributo}\" para monotributo.`,\n },\n \"salesPoint.blocked\": {\n diagnosis: \"El punto de venta {salesPoint} está bloqueado.\",\n fix: \"Revisalo en ARCA.\",\n },\n};\n\n/** Resolves one row and fills its `{placeholders}`. */\nexport function diagnose(\n key: CliDiagnosisKey,\n values: CliDiagnosisValues = {}\n): CliDiagnosis {\n const row = CLI_DIAGNOSES[key];\n return {\n diagnosis: fill(row.diagnosis, values),\n ...(row.fix === undefined ? {} : { fix: fill(row.fix, values) }),\n };\n}\n\n/** Maps `ArcaAuthenticationError.reason` to its row. */\nexport function diagnoseAuthenticationReason(\n reason: ArcaAuthenticationReason\n): CliDiagnosis {\n return diagnose(`wsfe.${reason}`);\n}\n\nconst WSAA_FAULT_ROWS: Readonly<Record<string, CliDiagnosisKey>> = {\n \"cms.cert.expired\": \"wsaa.certExpired\",\n \"cms.cert.untrusted\": \"wsaa.certUntrusted\",\n \"cms.cert.invalid\": \"wsaa.certUntrusted\",\n \"cms.cert.notfound\": \"wsaa.certUntrusted\",\n \"cms.bad\": \"wsaa.signInvalid\",\n \"cms.sign.invalid\": \"wsaa.signInvalid\",\n \"coe.notauthorized\": \"wsaa.notAuthorized\",\n \"coe.alreadyauthenticated\": \"wsaa.alreadyAuthenticated\",\n \"xml.generationtime.invalid\": \"wsaa.clockSkew\",\n \"xml.expirationtime.invalid\": \"wsaa.clockSkew\",\n \"xml.expirationtime.expired\": \"wsaa.clockSkew\",\n};\n\n/**\n * Maps a WSAA SOAP fault code to its row. ARCA prefixes the code with a SOAP\n * namespace (`ns1:coe.notAuthorized`), so the prefix is dropped first.\n */\nexport function diagnoseWsaaFaultCode(\n faultCode: string | undefined\n): CliDiagnosisKey | undefined {\n if (faultCode === undefined) {\n return undefined;\n }\n const bare = faultCode.slice(faultCode.indexOf(\":\") + 1).toLowerCase();\n const exact = WSAA_FAULT_ROWS[bare];\n if (exact) {\n return exact;\n }\n return bare.startsWith(\"xml.expirationtime.\") ? \"wsaa.clockSkew\" : undefined;\n}\n\n/** The SOAP fault carried by an error, or by the error the SDK wrapped it in. */\nexport function findSoapFault(error: unknown): ArcaSoapFaultError | undefined {\n if (error instanceof ArcaSoapFaultError) {\n return error;\n }\n const cause = error instanceof Error ? error.cause : undefined;\n return cause instanceof ArcaSoapFaultError ? cause : undefined;\n}\n\n/** The transport failure carried by an error, or by its cause. */\nexport function findTransportError(\n error: unknown\n): ArcaTransportError | undefined {\n if (error instanceof ArcaTransportError) {\n return error;\n }\n const cause = error instanceof Error ? error.cause : undefined;\n return cause instanceof ArcaTransportError ? cause : undefined;\n}\n\n/** Fallback for anything the table does not name. Never prints credentials. */\nexport function describeUnknownError(error: unknown): {\n diagnosis: string;\n code?: string;\n} {\n const safe = toArcaSafeErrorMetadata(error);\n return {\n diagnosis: safe.message,\n ...(safe.code === undefined ? {} : { code: safe.code }),\n };\n}\n\nfunction fill(text: string, values: CliDiagnosisValues): string {\n return text.replace(\n /\\{(certificateTaxId|date|file|files|host|message|missingFile|salesPoint|taxId)\\}/g,\n (match, key) => {\n const value = values[key as keyof CliDiagnosisValues];\n return value === undefined ? match : String(value);\n }\n );\n}\n","import { spawn as spawnProcess } from \"node:child_process\";\n\n/**\n * The system clipboard, through the tool each platform already ships. There is\n * no dependency and no shell: the text goes to the process' stdin, so nothing\n * a CSR contains can ever be read as a command. Every failure —no binary, no\n * display, a non-zero exit, a hang— is the same answer, `false`, and the CLI\n * prints the CSR instead.\n */\n\n/** How long a clipboard tool has to take the text before the CLI moves on. */\nconst TIMEOUT_MS = 2000;\n\ntype ClipboardStdin = {\n write(chunk: string): unknown;\n end(): unknown;\n on(event: \"error\", listener: (error: Error) => void): unknown;\n};\n\n/** The little of a child process this module uses. Tests pass a fake. */\nexport type ClipboardProcess = {\n stdin: ClipboardStdin | null;\n on(event: \"error\", listener: (error: Error) => void): unknown;\n on(event: \"close\", listener: (code: number | null) => void): unknown;\n kill(): unknown;\n};\n\n/** `child_process.spawn`, narrowed to what the clipboard needs. */\nexport type ClipboardSpawn = (\n command: string,\n args: readonly string[]\n) => ClipboardProcess;\n\nexport type ClipboardOptions = {\n spawn?: ClipboardSpawn;\n platform?: string;\n env?: Record<string, string | undefined>;\n /** Only tests pass this. */\n timeoutMs?: number;\n};\n\ntype ClipboardCommand = { command: string; args: string[] };\n\n/**\n * The tools worth trying, in order, for one platform. Empty means \"no\n * clipboard here\": a headless Linux box, an SSH session —where the tool would\n * write to the clipboard of the wrong machine— or an unknown platform.\n */\nexport function clipboardCommands(\n platform: string,\n env: Record<string, string | undefined>\n): ClipboardCommand[] {\n if (env.SSH_CONNECTION !== undefined || env.SSH_TTY !== undefined) {\n return [];\n }\n if (platform === \"darwin\") {\n return [{ command: \"pbcopy\", args: [] }];\n }\n if (platform === \"win32\") {\n return [{ command: \"clip\", args: [] }];\n }\n const commands: ClipboardCommand[] = [];\n if (env.WAYLAND_DISPLAY !== undefined) {\n commands.push({ command: \"wl-copy\", args: [] });\n }\n if (env.DISPLAY !== undefined) {\n commands.push(\n { command: \"xclip\", args: [\"-selection\", \"clipboard\"] },\n { command: \"xsel\", args: [\"--clipboard\", \"--input\"] }\n );\n }\n return commands;\n}\n\n/**\n * Puts `text` in the system clipboard. Never throws and never writes anything\n * to the terminal: the caller decides what to say about `false`.\n */\nexport async function copyToClipboard(\n text: string,\n options: ClipboardOptions = {}\n): Promise<boolean> {\n const spawn =\n options.spawn ??\n ((command, args) =>\n spawnProcess(command, [...args], {\n stdio: [\"pipe\", \"ignore\", \"ignore\"],\n }) as ClipboardProcess);\n const commands = clipboardCommands(\n options.platform ?? process.platform,\n options.env ?? process.env\n );\n\n for (const candidate of commands) {\n // Sequential on purpose: the second tool is the fallback of the first,\n // and running both would put the text in the clipboard twice.\n const copied = await feed(\n spawn,\n candidate,\n text,\n options.timeoutMs ?? TIMEOUT_MS\n );\n if (copied) {\n return true;\n }\n }\n return false;\n}\n\n/** Runs one tool and answers whether it took the text. */\nfunction feed(\n spawn: ClipboardSpawn,\n candidate: ClipboardCommand,\n text: string,\n timeoutMs: number\n): Promise<boolean> {\n return new Promise<boolean>((done) => {\n let settled = false;\n let timer: NodeJS.Timeout | undefined;\n const finish = (copied: boolean) => {\n if (settled) {\n return;\n }\n settled = true;\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n done(copied);\n };\n\n let child: ClipboardProcess;\n try {\n child = spawn(candidate.command, candidate.args);\n } catch {\n finish(false);\n return;\n }\n\n timer = setTimeout(() => {\n child.kill();\n finish(false);\n }, timeoutMs);\n child.on(\"error\", () => finish(false));\n child.on(\"close\", (code) => finish(code === 0));\n\n const stdin = child.stdin;\n if (stdin === null) {\n finish(false);\n return;\n }\n stdin.on(\"error\", () => finish(false));\n try {\n stdin.write(text);\n stdin.end();\n } catch {\n finish(false);\n }\n });\n}\n","import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst MAX_DEPTH = 5;\n\n/**\n * Reads the published version from the nearest `package.json`. Walking up is\n * needed because the bundled `dist/cli.mjs` and `src/cli/version.ts` sit at\n * different depths from the manifest.\n */\nexport function readCliVersion(): string {\n let directory = dirname(fileURLToPath(import.meta.url));\n for (let depth = 0; depth < MAX_DEPTH; depth += 1) {\n try {\n const raw = readFileSync(join(directory, \"package.json\"), \"utf8\");\n const parsed = JSON.parse(raw) as { version?: string };\n if (typeof parsed.version === \"string\") {\n return parsed.version;\n }\n } catch {\n // Keep walking up: bundled output and source sit at different depths.\n }\n directory = dirname(directory);\n }\n return \"0.0.0\";\n}\n","import { createPainter } from \"./output\";\nimport { readCliVersion } from \"./version\";\n\n/** One help page: the root one, or one per command. */\nexport type CliHelpTopic = \"root\" | \"init\" | \"cert\" | \"check\" | \"issue\";\n\ntype HelpRow = { name: string; description?: string };\n\ntype HelpSection = {\n title: string;\n rows: HelpRow[];\n /** Names in bold. Only the command list uses it; flags stay plain. */\n bold?: boolean;\n};\n\ntype HelpPage = {\n /** One line saying what the command does. The root page has none. */\n summary?: string;\n usage: string;\n sections: HelpSection[];\n examples: string[];\n /** What the command writes, caches or touches. Short, never a paragraph. */\n notes?: string[];\n};\n\nconst INDENT = \" \";\n/** Spaces between the widest name of a section and its description column. */\nconst COLUMN_GAP = 3;\n\n/** What each command does, in the words the root page and the docs use. */\nexport const CLI_COMMAND_SUMMARIES = {\n init: \"clave privada y CSR, más los pasos exactos en ARCA\",\n cert: \"pega el certificado que te dio ARCA y lo guarda\",\n check: \"prueba cada capa en orden y nombra la que falla\",\n issue: \"una factura de ARS 1 en homologación, solo a pedido\",\n} as const;\n\nconst HELP_PAGES: Record<CliHelpTopic, HelpPage> = {\n root: {\n usage: \"npx facturas <comando> [opciones]\",\n sections: [\n {\n title: \"Comandos:\",\n bold: true,\n rows: [\n { name: \"init\", description: CLI_COMMAND_SUMMARIES.init },\n { name: \"cert\", description: CLI_COMMAND_SUMMARIES.cert },\n { name: \"check\", description: CLI_COMMAND_SUMMARIES.check },\n { name: \"issue\", description: CLI_COMMAND_SUMMARIES.issue },\n ],\n },\n {\n title: \"Opciones globales:\",\n rows: [\n { name: \"--json\", description: \"salida JSON (check e issue)\" },\n { name: \"--no-color\", description: \"sin colores\" },\n {\n name: \"-h, --help\",\n description: \"ayuda de un comando: npx facturas check --help\",\n },\n { name: \"-v, --version\" },\n ],\n },\n ],\n examples: [\n \"npx facturas init --cuit 20123456786 --env test\",\n \"npx facturas check\",\n \"npx facturas issue --sales-point 3 --issuer monotributo\",\n ],\n },\n init: {\n summary: CLI_COMMAND_SUMMARIES.init,\n usage: \"npx facturas init [opciones]\",\n sections: [\n {\n title: \"Opciones:\",\n rows: [\n {\n name: \"--cuit <cuit>\",\n description: \"CUIT de 11 dígitos, con o sin guiones\",\n },\n {\n name: \"--env <test|production>\",\n description: \"entorno de destino\",\n },\n {\n name: \"--name <alias>\",\n description: \"common name del CSR (por defecto: facturas)\",\n },\n {\n name: \"--org <razón social>\",\n description: \"organización del CSR (por defecto: el CUIT)\",\n },\n {\n name: \"--dir <directorio>\",\n description: \"dónde escribir los archivos (por defecto: el actual)\",\n },\n {\n name: \"--force\",\n description: \"sobrescribe los archivos existentes\",\n },\n {\n name: \"--no-clipboard\",\n description: \"no copia el CSR al portapapeles\",\n },\n {\n name: \"--no-paste\",\n description: \"no pregunta por el certificado al final\",\n },\n { name: \"--no-color\", description: \"sin colores\" },\n { name: \"-h, --help\", description: \"esta ayuda\" },\n ],\n },\n ],\n examples: [\n \"npx facturas init --cuit 20123456786 --env test\",\n \"npx facturas init --cuit 20-12345678-6 --env production --name mi-sistema\",\n ],\n notes: [\n \"Escribe arca-<entorno>.key con permisos 0600 y arca-<entorno>.csr, y\",\n \"nunca escribe en ARCA. En homologación copia el CSR al portapapeles, y\",\n \"si no puede lo imprime para copiarlo de la terminal. Al final pide el\",\n \"certificado y lo guarda como arca-<entorno>.crt; con Ctrl-C, --no-paste\",\n \"o sin terminal, lo guardás vos o lo pegás después con cert. En una\",\n \"terminal pregunta el CUIT y el entorno; sin terminal, --cuit y --env\",\n \"son obligatorios.\",\n ],\n },\n cert: {\n summary: CLI_COMMAND_SUMMARIES.cert,\n usage: \"npx facturas cert [opciones]\",\n sections: [\n {\n title: \"Opciones:\",\n rows: [\n {\n name: \"--env <test|production>\",\n description: \"cuál par usar si están los dos\",\n },\n {\n name: \"--dir <directorio>\",\n description: \"dónde están los archivos (por defecto: el actual)\",\n },\n {\n name: \"--force\",\n description: \"sobrescribe el certificado existente\",\n },\n { name: \"--no-color\", description: \"sin colores\" },\n { name: \"-h, --help\", description: \"esta ayuda\" },\n ],\n },\n ],\n examples: [\n \"npx facturas cert\",\n \"npx facturas cert --env production\",\n \"npx facturas cert --dir credenciales --force\",\n ],\n notes: [\n \"Pegás el certificado que te dio ARCA, de -----BEGIN CERTIFICATE----- a\",\n \"-----END CERTIFICATE-----, y lo guarda como arca-<entorno>.crt junto a\",\n \"la clave que generó init. Antes verifica que sea el certificado de esa\",\n \"clave y de ese CUIT, y si no, no escribe nada. Es lo mismo que init\",\n \"pregunta al final: cert está para cuando lo dejaste para después.\",\n ],\n },\n check: {\n summary: CLI_COMMAND_SUMMARIES.check,\n usage: \"npx facturas check [opciones]\",\n sections: [\n {\n title: \"Opciones:\",\n rows: [\n {\n name: \"--cert <archivo>\",\n description: \"certificado PEM desde un archivo\",\n },\n {\n name: \"--key <archivo>\",\n description: \"clave privada PEM desde un archivo\",\n },\n {\n name: \"--cuit <cuit>\",\n description: \"CUIT, en lugar de ARCA_TAX_ID\",\n },\n {\n name: \"--env <test|production>\",\n description: \"entorno, en lugar de ARCA_ENVIRONMENT\",\n },\n {\n name: \"--dir <directorio>\",\n description: \"dónde buscar los archivos (por defecto: el actual)\",\n },\n {\n name: \"--sales-point <n>\",\n description: \"punto de venta a verificar\",\n },\n {\n name: \"--no-cache\",\n description: \"no reusa ni guarda el ticket WSAA\",\n },\n { name: \"--json\", description: \"salida JSON\" },\n { name: \"--no-color\", description: \"sin colores\" },\n { name: \"-h, --help\", description: \"esta ayuda\" },\n ],\n },\n ],\n examples: [\n \"npx facturas check\",\n \"npx facturas check --sales-point 3\",\n \"npx facturas check --cert arca-test.crt --key arca-test.key\",\n ],\n notes: [\n \"Busca cada valor en este orden: los flags, las variables de entorno y,\",\n \"por último, arca-<entorno>.crt y arca-<entorno>.key en el directorio; de\",\n \"ahí sale también el CUIT y el entorno. Nunca escribe en ARCA: solo lee.\",\n \"Guarda el ticket WSAA en el directorio temporal del sistema para poder\",\n \"repetirse, porque ARCA rechaza un segundo login mientras hay uno\",\n \"vigente; --no-cache no lo lee ni lo escribe.\",\n ],\n },\n issue: {\n summary: CLI_COMMAND_SUMMARIES.issue,\n usage: \"npx facturas issue [opciones]\",\n sections: [\n {\n title: \"Opciones:\",\n rows: [\n { name: \"--sales-point <n>\", description: \"punto de venta a usar\" },\n { name: \"--issuer <condición>\", description: \"condición del emisor\" },\n {\n name: \"--cert <archivo>\",\n description: \"certificado PEM desde un archivo\",\n },\n {\n name: \"--key <archivo>\",\n description: \"clave privada PEM desde un archivo\",\n },\n {\n name: \"--cuit <cuit>\",\n description: \"CUIT, en lugar de ARCA_TAX_ID\",\n },\n {\n name: \"--env <test|production>\",\n description: \"entorno, en lugar de ARCA_ENVIRONMENT\",\n },\n {\n name: \"--dir <directorio>\",\n description: \"dónde buscar los archivos (por defecto: el actual)\",\n },\n {\n name: \"--no-cache\",\n description: \"no reusa ni guarda el ticket WSAA\",\n },\n { name: \"--json\", description: \"salida JSON\" },\n { name: \"--no-color\", description: \"sin colores\" },\n { name: \"-h, --help\", description: \"esta ayuda\" },\n ],\n },\n ],\n examples: [\n \"npx facturas issue --sales-point 3 --issuer monotributo\",\n \"npx facturas issue --sales-point 3 --issuer responsable_inscripto --json\",\n ],\n notes: [\n \"Las condiciones de emisor son monotributo, responsable_inscripto,\",\n \"exento y no_alcanzado. Emite un comprobante real de homologación y se\",\n \"niega fuera de test: corre antes las capas de check, con la misma\",\n \"búsqueda de configuración, y no sigue si alguna falla. En una terminal\",\n \"pregunta el punto de venta y el emisor.\",\n ],\n },\n};\n\n/**\n * Renders one help page. Pure: the same text with and without ANSI, so\n * `--no-color` output is the colored one minus the escapes.\n */\nexport function renderHelp(\n topic: CliHelpTopic,\n options: { color: boolean }\n): string {\n const painter = createPainter(options.color);\n const page = HELP_PAGES[topic];\n const lines = [`facturas ${readCliVersion()}`, \"\"];\n\n if (page.summary !== undefined) {\n lines.push(`${INDENT}${page.summary}`, \"\");\n }\n lines.push(`${INDENT}${page.usage}`, \"\");\n\n for (const section of page.sections) {\n lines.push(painter.dim(section.title), \"\");\n const width = columnWidth(section.rows);\n for (const row of section.rows) {\n const name = section.bold === true ? painter.bold(row.name) : row.name;\n lines.push(\n row.description === undefined\n ? `${INDENT}${name}`\n : `${INDENT}${name}${\" \".repeat(width - row.name.length)}${row.description}`\n );\n }\n lines.push(\"\");\n }\n\n lines.push(painter.dim(\"Ejemplos:\"), \"\");\n for (const example of page.examples) {\n lines.push(`${INDENT}${painter.dim(\"$\")} ${painter.cyan(example)}`);\n }\n\n if (page.notes !== undefined) {\n lines.push(\"\", painter.dim(\"Notas:\"), \"\");\n for (const note of page.notes) {\n lines.push(`${INDENT}${note}`);\n }\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\n/** Where the descriptions start. Rows without one never widen the column. */\nfunction columnWidth(rows: HelpRow[]): number {\n const widest = rows\n .filter((row) => row.description !== undefined)\n .reduce((longest, row) => Math.max(longest, row.name.length), 0);\n return widest + COLUMN_GAP;\n}\n","import {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport type { ArcaEnvironment } from \"../internal/types\";\nimport { type ArcaPlanContext, buildArcaPlan } from \"./arca-steps\";\nimport { pasteCertificate, writeManualHint } from \"./cert\";\nimport { createArcaCsrMaterial } from \"./csr\";\nimport { describeTaxIdProblem, normalizeTaxId } from \"./cuit\";\nimport { toEnvironment } from \"./discover\";\nimport { CLI_EXIT, type CliIo, type CliWriter } from \"./output\";\nimport { ask, isInteractive } from \"./prompt\";\n\nconst KEY_FILE_MODE = 0o600;\n/** Three tries at the prompt before the CLI gives up and says why. */\nconst TAX_ID_ATTEMPTS = 3;\nconst MISSING_TAX_ID =\n \"Falta el CUIT. Pasá --cuit 20123456786 o ejecutá init en una terminal.\";\nconst MISSING_ENVIRONMENT =\n \"Falta el entorno. Pasá --env test o --env production.\";\nconst GITIGNORE_PATTERNS = [\"arca-*.key\", \"arca-*.crt\"] as const;\n\nexport type InitFlags = {\n cuit?: string;\n env?: string;\n name?: string;\n dir?: string;\n force?: boolean;\n org?: string;\n /** Leaves the clipboard alone: the CSR gets printed instead. */\n noClipboard?: boolean;\n /** Skips the certificate prompt at the end. */\n noPaste?: boolean;\n};\n\n/** Generates the key and the CSR, then prints the exact ARCA steps. */\nexport async function runInit(\n io: CliIo,\n flags: InitFlags,\n writer: CliWriter\n): Promise<number> {\n const resolved = await resolveInitInput(io, flags);\n if (resolved === undefined) {\n return CLI_EXIT.usage;\n }\n\n const { taxId, environment } = resolved;\n const directory = isAbsolute(flags.dir ?? \"\")\n ? (flags.dir as string)\n : resolve(io.cwd, flags.dir ?? \".\");\n const commonName = flags.name?.trim() || \"facturas\";\n // ARCA's alias fields accept letters and digits only, so the alias is the\n // common name with everything else dropped, plus the environment.\n const alias = `${commonName.replace(/[^A-Za-z0-9]/g, \"\")}${\n environment === \"test\" ? \"Test\" : \"Production\"\n }`;\n const keyName = `arca-${environment}.key`;\n const csrName = `arca-${environment}.csr`;\n const certificateName = `arca-${environment}.crt`;\n const keyPath = resolve(directory, keyName);\n const csrPath = resolve(directory, csrName);\n\n const existing = [keyPath, csrPath].filter((path) => existsSync(path));\n if (existing.length > 0 && flags.force !== true) {\n io.stderr.write(\n `Ya existe ${existing.map((path) => path).join(\" y \")}. Usá --force para sobrescribir.\\n`\n );\n return CLI_EXIT.failed;\n }\n\n const material = createArcaCsrMaterial({\n taxId,\n commonName,\n organization: flags.org?.trim() || taxId,\n });\n mkdirSync(directory, { recursive: true });\n writeFileSync(keyPath, material.privateKeyPem, { mode: KEY_FILE_MODE });\n chmodSync(keyPath, KEY_FILE_MODE);\n writeFileSync(csrPath, material.csrPem);\n\n // Only homologación pastes the CSR into a form: production uploads the file\n // itself, so there is nothing to put in the clipboard.\n const clipboard =\n environment === \"test\" &&\n flags.noClipboard !== true &&\n (await io.copyToClipboard(material.csrPem));\n\n writer.ok(keyName, \"clave privada RSA 2048, permisos 0600\");\n writer.ok(csrName, `CSR para ARCA, CN=${commonName}`);\n if (clipboard) {\n writer.ok(\"portapapeles\", `${csrName} copiado, pegalo en el paso 3`);\n }\n\n const ignored = appendToGitignore(directory);\n if (ignored.length > 0) {\n writer.ok(\".gitignore\", `agregué ${ignored.join(\" y \")}`);\n }\n\n const paste = flags.noPaste !== true && isInteractive(io);\n writePlan(writer, {\n alias,\n certificateName,\n clipboard,\n csrName,\n csrPem: material.csrPem,\n environment,\n paste,\n taxId,\n });\n\n const code = paste\n ? await askForCertificate(io, writer, {\n certificatePath: resolve(directory, certificateName),\n certificateName,\n keyName,\n privateKeyPem: material.privateKeyPem,\n taxId,\n })\n : manualCertificate(writer, certificateName);\n\n writer.blank();\n writer.dim(\"Para tu app las variables son ARCA_TAX_ID, ARCA_ENVIRONMENT,\");\n writer.dim(\n \"ARCA_CERTIFICATE_PEM y ARCA_PRIVATE_KEY_PEM; ver docs/inicio-rapido.md.\"\n );\n return code;\n}\n\n/**\n * The certificate, right here, while the browser tab with it is still open.\n * A saved file the CLI never sees is the step where onboarding used to end.\n */\nasync function askForCertificate(\n io: CliIo,\n writer: CliWriter,\n request: {\n certificatePath: string;\n certificateName: string;\n keyName: string;\n privateKeyPem: string;\n taxId: string;\n }\n): Promise<number> {\n const outcome = await pasteCertificate(io, writer, {\n intro: [\n \"Cuando tengas el certificado (paso 4), pegalo acá. Termina solo al ver\",\n \"-----END CERTIFICATE-----. Ctrl-C para hacerlo después con\",\n \"npx facturas cert.\",\n ],\n ...request,\n });\n\n if (outcome === \"saved\") {\n writer.blank();\n writer.line(\"Falta el paso 5 (la autorización a wsfe). Cuando esté:\");\n writer.blank();\n writer.command(\"npx facturas check\");\n return CLI_EXIT.ok;\n }\n if (outcome === \"refused\") {\n return CLI_EXIT.failed;\n }\n writeManualHint(writer, request.certificateName);\n return outcome === \"cancelled\" ? CLI_EXIT.ok : CLI_EXIT.failed;\n}\n\n/** Without a terminal, or with --no-paste, the old hand-off is still true. */\nfunction manualCertificate(writer: CliWriter, certificateName: string): number {\n writeManualHint(writer, certificateName);\n return CLI_EXIT.ok;\n}\n\nasync function resolveInitInput(\n io: CliIo,\n flags: InitFlags\n): Promise<{ taxId: string; environment: ArcaEnvironment } | undefined> {\n const interactive = isInteractive(io);\n const taxId = await resolveTaxId(io, flags, interactive);\n if (\"error\" in taxId) {\n io.stderr.write(`${taxId.error}\\n`);\n return undefined;\n }\n\n const environment = await resolveEnvironment(io, flags, interactive);\n if (environment === undefined) {\n io.stderr.write(`${MISSING_ENVIRONMENT}\\n`);\n return undefined;\n }\n\n return { taxId: taxId.taxId, environment };\n}\n\n/**\n * A CUIT that is absent and one that is wrong are different problems, and the\n * message has to say which. On a terminal a wrong answer is worth another try:\n * the reason goes back to the user and the question is asked again.\n */\nasync function resolveTaxId(\n io: CliIo,\n flags: InitFlags,\n interactive: boolean\n): Promise<{ taxId: string } | { error: string }> {\n const fromFlag = flags.cuit?.trim();\n if (fromFlag !== undefined && fromFlag !== \"\") {\n const problem = describeTaxIdProblem(fromFlag);\n return problem === undefined\n ? { taxId: normalizeTaxId(fromFlag) }\n : { error: problem };\n }\n if (!interactive) {\n return { error: MISSING_TAX_ID };\n }\n\n let problem = MISSING_TAX_ID;\n for (let attempt = 1; attempt <= TAX_ID_ATTEMPTS; attempt += 1) {\n const answer = await ask(io, \"CUIT: \");\n if (answer === \"\") {\n problem = MISSING_TAX_ID;\n } else {\n const invalid = describeTaxIdProblem(answer);\n if (invalid === undefined) {\n return { taxId: normalizeTaxId(answer) };\n }\n problem = invalid;\n }\n if (attempt < TAX_ID_ATTEMPTS) {\n io.stderr.write(`${problem}\\n`);\n }\n }\n return { error: problem };\n}\n\nasync function resolveEnvironment(\n io: CliIo,\n flags: InitFlags,\n interactive: boolean\n): Promise<ArcaEnvironment | undefined> {\n const fromFlag = flags.env?.trim().toLowerCase();\n if (fromFlag !== undefined && fromFlag !== \"\") {\n return toEnvironment(fromFlag);\n }\n if (!interactive) {\n return undefined;\n }\n const answer = await ask(io, \"Entorno [test/production]: \");\n return toEnvironment(answer.trim().toLowerCase());\n}\n\n/** Appends the credential patterns to an existing `.gitignore`. Idempotent. */\nfunction appendToGitignore(directory: string): string[] {\n const path = resolve(directory, \".gitignore\");\n if (!existsSync(path)) {\n return [];\n }\n\n const current = readFileSync(path, \"utf8\");\n const lines = new Set(current.split(\"\\n\").map((line) => line.trim()));\n const missing = GITIGNORE_PATTERNS.filter((pattern) => !lines.has(pattern));\n if (missing.length === 0) {\n return [];\n }\n\n const prefix = current.length > 0 && !current.endsWith(\"\\n\") ? \"\\n\" : \"\";\n writeFileSync(path, `${current}${prefix}${missing.join(\"\\n\")}\\n`);\n return [...missing];\n}\n\nfunction writePlan(\n writer: CliWriter,\n context: ArcaPlanContext & { environment: ArcaEnvironment }\n): void {\n const plan = buildArcaPlan(context.environment, context, writer.painter);\n writer.blank();\n writer.line(plan.heading);\n writer.blank();\n for (const line of plan.lines) {\n writer.line(line.text);\n }\n}\n","import type { IssuedVoucher, IssueOutcome } from \"../services/vouchers-types\";\nimport type { IssueInput } from \"../services/wsfe-derive\";\nimport {\n type CheckFlags,\n type CliCheckReport,\n parseSalesPoint,\n resolveCheckEnvironment,\n runCheckLayers,\n writeCheckReport,\n} from \"./check\";\nimport { describeUnknownError } from \"./diagnose\";\nimport { CLI_EXIT, type CliIo, type CliWriter } from \"./output\";\nimport { ask, isInteractive } from \"./prompt\";\n\n/** One peso, in minor units. The smoke test never issues more than this. */\nconst SMOKE_TEST_MINOR_UNITS = 100;\nconst SMOKE_TEST_VAT_RATE = 21;\nconst SALES_POINT_DIGITS = 5;\nconst VOUCHER_NUMBER_DIGITS = 8;\n\nconst ISSUER_CONDITIONS = [\n \"monotributo\",\n \"responsable_inscripto\",\n \"exento\",\n \"no_alcanzado\",\n] as const;\n\ntype IssuerCondition = (typeof ISSUER_CONDITIONS)[number];\n\n/**\n * The smoke test always builds an items input, never the reviewed-amounts one,\n * so `items` is present and the printed call can read it without a guard.\n */\ntype SmokeTestItem = { gross: number; vat: number } | { amount: number };\ntype SmokeTestInput = IssueInput & { items: readonly SmokeTestItem[] };\n\nexport type IssueFlags = CheckFlags & {\n issuer?: string;\n};\n\n/** Issues exactly one ARS 1 invoice in homologación. Refuses anywhere else. */\nexport async function runIssue(\n io: CliIo,\n flags: IssueFlags,\n writer: CliWriter,\n json: boolean\n): Promise<number> {\n // Refuse before anything else when the environment is already known to be\n // the wrong one. When nothing says which it is, the check layers run and\n // name the real problem, and the guard below runs again on what they found.\n const environment = resolveCheckEnvironment(io, flags);\n if (environment !== undefined && environment !== \"test\") {\n return refuse(io);\n }\n\n const parameters = await resolveIssueInput(io, flags);\n if (parameters === undefined) {\n return CLI_EXIT.usage;\n }\n\n const { report, client } = await runCheckLayers(io, flags);\n if (!(report.ok && client)) {\n if (json) {\n writer.json(report);\n } else {\n writeCheckReport(writer, report);\n }\n return CLI_EXIT.failed;\n }\n if (report.environment !== \"test\") {\n return refuse(io);\n }\n\n const input = buildSmokeTestInput(parameters.issuer, parameters.salesPoint);\n // The layers passed, so ARCA answered a moment ago; it can still fail on the\n // next number or the authorization. That is a diagnosis like any other, not\n // a stack trace, and with --json it still has to be one JSON object.\n let outcome: IssueOutcome;\n try {\n outcome = await client.issue(input);\n } catch (error) {\n return writeIssueError(writer, report, error, json);\n }\n if (json) {\n writer.json(outcome);\n return outcome.kind === \"authorized\" ? CLI_EXIT.ok : CLI_EXIT.failed;\n }\n return writeOutcome(writer, outcome, input);\n}\n\n/** The same safe message and code the check layers print, in both shapes. */\nfunction writeIssueError(\n writer: CliWriter,\n report: CliCheckReport,\n error: unknown,\n json: boolean\n): number {\n const unknown = describeUnknownError(error);\n if (json) {\n writer.json({\n ok: false,\n ...(report.environment === undefined\n ? {}\n : { environment: report.environment }),\n ...(report.taxId === undefined ? {} : { taxId: report.taxId }),\n error: {\n ...(unknown.code === undefined ? {} : { code: unknown.code }),\n message: unknown.diagnosis,\n },\n });\n return CLI_EXIT.failed;\n }\n writer.fail(\"emisión\");\n writer.note(unknown.diagnosis);\n writer.note(\n \"No sabemos si ARCA llegó a autorizar; consultá el punto de venta antes de repetir.\"\n );\n return CLI_EXIT.failed;\n}\n\nfunction refuse(io: CliIo): number {\n io.stderr.write(\n \"issue solo emite en homologación. Cambiá ARCA_ENVIRONMENT=test.\\n\"\n );\n return CLI_EXIT.failed;\n}\n\nasync function resolveIssueInput(\n io: CliIo,\n flags: IssueFlags\n): Promise<{ issuer: IssuerCondition; salesPoint: number } | undefined> {\n const interactive = isInteractive(io);\n const salesPoint = await resolveSalesPoint(io, flags, interactive);\n if (salesPoint === undefined) {\n io.stderr.write(\"Falta el punto de venta. Pasá --sales-point 3.\\n\");\n return undefined;\n }\n\n const issuer = await resolveIssuer(io, flags, interactive);\n if (issuer === undefined) {\n io.stderr.write(\n `Falta la condición del emisor. Pasá --issuer ${ISSUER_CONDITIONS.join(\"|\")}.\\n`\n );\n return undefined;\n }\n\n return { issuer, salesPoint };\n}\n\nasync function resolveSalesPoint(\n io: CliIo,\n flags: IssueFlags,\n interactive: boolean\n): Promise<number | undefined> {\n if (flags.salesPoint !== undefined) {\n return flags.salesPoint;\n }\n if (!interactive) {\n return undefined;\n }\n // The same reading as `--sales-point`: a typo is a typo at the prompt too.\n return parseSalesPoint((await ask(io, \"Punto de venta: \")).trim());\n}\n\nasync function resolveIssuer(\n io: CliIo,\n flags: IssueFlags,\n interactive: boolean\n): Promise<IssuerCondition | undefined> {\n const fromFlag = flags.issuer?.trim();\n if (fromFlag) {\n return toIssuerCondition(fromFlag);\n }\n if (!interactive) {\n return undefined;\n }\n const answer = await ask(io, `Emisor [${ISSUER_CONDITIONS.join(\"/\")}]: `);\n return toIssuerCondition(answer.trim());\n}\n\nfunction toIssuerCondition(value: string): IssuerCondition | undefined {\n return ISSUER_CONDITIONS.includes(value as IssuerCondition)\n ? (value as IssuerCondition)\n : undefined;\n}\n\n/** ARS 1: a VAT item for class B, a plain amount for class C. */\nexport function buildSmokeTestInput(\n issuer: IssuerCondition,\n salesPoint: number\n): SmokeTestInput {\n if (issuer === \"responsable_inscripto\") {\n return {\n issuer,\n salesPoint,\n to: { condition: \"consumidor_final\" },\n items: [{ gross: SMOKE_TEST_MINOR_UNITS, vat: SMOKE_TEST_VAT_RATE }],\n };\n }\n return {\n issuer,\n salesPoint,\n to: { condition: \"consumidor_final\" },\n items: [{ amount: SMOKE_TEST_MINOR_UNITS }],\n };\n}\n\nfunction writeOutcome(\n writer: CliWriter,\n outcome: IssueOutcome,\n input: SmokeTestInput\n): number {\n if (outcome.kind === \"authorized\") {\n writer.ok(describeVoucher(outcome.voucher));\n writeIssueCall(writer, input);\n return CLI_EXIT.ok;\n }\n\n if (outcome.kind === \"rejected\") {\n writer.fail(\n `Factura rechazada - ${describeCoordinates(outcome.attempted)}`\n );\n for (const issue of outcome.issues) {\n writer.note(\n issue.code === undefined\n ? issue.message\n : `${issue.code} ${issue.message}`\n );\n }\n return CLI_EXIT.failed;\n }\n\n if (outcome.kind === \"conflict\") {\n writer.fail(`conflicto en ${describeCoordinates(outcome.attempted)}`);\n writer.note(outcome.reason);\n writer.note(\n \"Hay otro comprobante en ese número; detené el flujo e investigá.\"\n );\n return CLI_EXIT.failed;\n }\n\n writer.fail(`indeterminado ${describeCoordinates(outcome.attempted)}`);\n writer.note(`${outcome.attempt.reason}, consulta ${outcome.lookup.kind}`);\n writer.note(\n \"Conservá el número y la evidencia; conciliá o repetí el mismo input con su clave.\"\n );\n return CLI_EXIT.failed;\n}\n\nfunction describeVoucher(voucher: IssuedVoucher): string {\n return [\n `Factura ${voucher.voucherClass} emitida - ${describeCoordinates(voucher)}`,\n `CAE ${voucher.cae}`,\n `Vto. CAE ${formatArcaDate(voucher.caeExpiry)}`,\n `ARS ${formatMinorUnits(voucher.amounts.sentTotal)}`,\n ].join(\" \");\n}\n\nfunction describeCoordinates(coordinates: {\n salesPoint: number;\n number: number;\n}): string {\n return `${String(coordinates.salesPoint).padStart(SALES_POINT_DIGITS, \"0\")}-${String(\n coordinates.number\n ).padStart(VOUCHER_NUMBER_DIGITS, \"0\")}`;\n}\n\n/** `20260916` as ARCA sends it becomes `2026-09-16`. */\nfunction formatArcaDate(value: string): string {\n return /^\\d{8}$/.test(value)\n ? `${value.slice(0, 4)}-${value.slice(4, 6)}-${value.slice(6, 8)}`\n : value;\n}\n\n/** Minor units to the castellano form: thousands with `.`, decimals with `,`. */\nexport function formatMinorUnits(minorUnits: number): string {\n const negative = minorUnits < 0;\n const digits = String(Math.abs(minorUnits)).padStart(3, \"0\");\n const whole = digits.slice(0, -2);\n const cents = digits.slice(-2);\n const grouped = whole.replace(/\\B(?=(\\d{3})+(?!\\d))/g, \".\");\n return `${negative ? \"-\" : \"\"}${grouped},${cents}`;\n}\n\n/** Prints the exact call, so the smoke test doubles as the first snippet. */\nfunction writeIssueCall(writer: CliWriter, input: SmokeTestInput): void {\n writer.blank();\n writer.line(\"Esta es la llamada que hizo el CLI. Pegala en tu aplicación:\");\n writer.blank();\n writer.line(\" const factura = await arca.issue({\");\n writer.line(` issuer: \"${input.issuer}\",`);\n writer.line(` salesPoint: ${input.salesPoint},`);\n writer.line(' to: { condition: \"consumidor_final\" },');\n writer.line(` items: [${input.items.map(formatItem).join(\", \")}],`);\n writer.line(\" });\");\n}\n\nfunction formatItem(item: SmokeTestItem): string {\n const fields = Object.entries(item)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => `${key}: ${String(value)}`);\n return `{ ${fields.join(\", \")} }`;\n}\n"],"mappings":"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","names":["join","existsSync","readFileSync","resolve","text","resolve","existsSync","readFileSync","readFileSync","isAbsolute","resolve","text","text","toEnvironment","isAbsolute","resolve","readFileSync","text","readFileSync","INDENT","COLUMN_GAP","columnWidth","existsSync","readFileSync","writeFileSync","isAbsolute","resolve","isAbsolute","resolve","existsSync","writeFileSync","resolveTaxId","problem","readFileSync","refuse","join","text"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/main.ts","../src/cli/cert.ts","../src/cli/csr.ts","../src/cli/discover.ts","../src/cli/output.ts","../src/cli/prompt.ts","../src/cli/check.ts","../src/cli/cuit.ts","../src/cli/arca-steps.ts","../src/cli/diagnose.ts","../src/cli/clipboard.ts","../src/cli/version.ts","../src/cli/help.ts","../src/cli/init.ts","../src/cli/issue.ts"],"sourcesContent":["import { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type ParseArgsConfig, parseArgs } from \"node:util\";\nimport { createArcaClient } from \"../client\";\nimport type { ArcaClientConfig } from \"../internal/types\";\nimport { createWsaaAuthModule } from \"../wsaa\";\nimport { type CertFlags, runCert } from \"./cert\";\nimport {\n type CheckFlags,\n describeSalesPointProblem,\n parseSalesPoint,\n runCheck,\n} from \"./check\";\nimport { copyToClipboard } from \"./clipboard\";\nimport { describeUnknownError } from \"./diagnose\";\nimport { type CliHelpTopic, renderHelp } from \"./help\";\nimport { type InitFlags, runInit } from \"./init\";\nimport { type IssueFlags, runIssue } from \"./issue\";\nimport {\n CLI_EXIT,\n type CliIo,\n type CliOutputStream,\n createWriter,\n shouldUseColor,\n} from \"./output\";\nimport { readCliVersion } from \"./version\";\n\nconst COMMANDS = [\"init\", \"cert\", \"check\", \"issue\"] as const;\ntype Command = (typeof COMMANDS)[number];\n\ntype OptionConfig = NonNullable<ParseArgsConfig[\"options\"]>;\n\nconst GLOBAL_OPTIONS: OptionConfig = {\n help: { type: \"boolean\", short: \"h\" },\n version: { type: \"boolean\", short: \"v\" },\n json: { type: \"boolean\" },\n \"no-color\": { type: \"boolean\" },\n};\n\nconst COMMAND_OPTIONS: Record<Command, OptionConfig> = {\n init: {\n ...GLOBAL_OPTIONS,\n cuit: { type: \"string\" },\n env: { type: \"string\" },\n name: { type: \"string\" },\n org: { type: \"string\" },\n dir: { type: \"string\" },\n force: { type: \"boolean\" },\n \"no-clipboard\": { type: \"boolean\" },\n \"no-paste\": { type: \"boolean\" },\n },\n cert: {\n ...GLOBAL_OPTIONS,\n env: { type: \"string\" },\n dir: { type: \"string\" },\n force: { type: \"boolean\" },\n },\n check: {\n ...GLOBAL_OPTIONS,\n cert: { type: \"string\" },\n key: { type: \"string\" },\n cuit: { type: \"string\" },\n env: { type: \"string\" },\n dir: { type: \"string\" },\n \"sales-point\": { type: \"string\" },\n \"no-cache\": { type: \"boolean\" },\n },\n issue: {\n ...GLOBAL_OPTIONS,\n cert: { type: \"string\" },\n key: { type: \"string\" },\n cuit: { type: \"string\" },\n env: { type: \"string\" },\n dir: { type: \"string\" },\n \"sales-point\": { type: \"string\" },\n \"no-cache\": { type: \"boolean\" },\n issuer: { type: \"string\" },\n },\n};\n\n/** Runs one CLI invocation and returns its exit code. Never calls `exit`. */\nexport async function run(argv: readonly string[], io: CliIo): Promise<number> {\n const command = argv.find((token) => !token.startsWith(\"-\"));\n const wantsHelp = argv.includes(\"--help\") || argv.includes(\"-h\");\n const wantsVersion = argv.includes(\"--version\") || argv.includes(\"-v\");\n const noColor = argv.includes(\"--no-color\");\n const help = (stream: CliOutputStream, topic: CliHelpTopic) =>\n renderHelp(topic, {\n color: shouldUseColor(stream, io.env, noColor),\n });\n\n if (wantsVersion) {\n io.stdout.write(`${readCliVersion()}\\n`);\n return CLI_EXIT.ok;\n }\n // `--help` never reaches ARCA, the filesystem or a prompt: it is the one\n // command that always works, even with the rest of the line malformed.\n if (wantsHelp) {\n io.stdout.write(help(io.stdout, isCommand(command) ? command : \"root\"));\n return CLI_EXIT.ok;\n }\n if (command === undefined) {\n io.stderr.write(help(io.stderr, \"root\"));\n return CLI_EXIT.usage;\n }\n if (!isCommand(command)) {\n io.stderr.write(\n `Comando desconocido: ${command}\\n\\n${help(io.stderr, \"root\")}`\n );\n return CLI_EXIT.usage;\n }\n\n let values: Record<string, string | boolean | undefined>;\n try {\n ({ values } = parseArgs({\n args: [...argv],\n options: COMMAND_OPTIONS[command],\n allowPositionals: true,\n strict: true,\n }) as { values: Record<string, string | boolean | undefined> });\n } catch (error) {\n io.stderr.write(\n `${describeParseError(error)}\\n\\n${help(io.stderr, command)}`\n );\n return CLI_EXIT.usage;\n }\n\n const json = values.json === true;\n const writer = createWriter(io.stdout, {\n color: shouldUseColor(io.stdout, io.env, noColor),\n });\n\n if (command === \"init\") {\n return await runInit(io, toInitFlags(values), writer);\n }\n if (command === \"cert\") {\n return await runCert(io, toCertFlags(values), writer);\n }\n\n const given = values[\"sales-point\"];\n const salesPoint =\n typeof given === \"string\" ? parseSalesPoint(given) : undefined;\n if (typeof given === \"string\" && salesPoint === undefined) {\n io.stderr.write(`${describeSalesPointProblem(given)}\\n`);\n return CLI_EXIT.usage;\n }\n\n const shared = toCheckFlags(values, salesPoint);\n if (command === \"check\") {\n return await runCheck(io, shared, writer, json);\n }\n return await runIssue(io, toIssueFlags(values, shared), writer, json);\n}\n\n/**\n * Entry point used by `bin/facturas.mjs`. Sets the process exit code. Nothing\n * reaches node's unhandled rejection handler from here: whatever a command\n * failed to catch comes out as the SDK's safe message, never a stack or a PEM.\n */\nexport async function main(\n argv: readonly string[] = process.argv.slice(2),\n io: CliIo = createDefaultIo()\n) {\n try {\n process.exitCode = await run(argv, io);\n } catch (error) {\n io.stderr.write(`${describeUnknownError(error).diagnosis}\\n`);\n process.exitCode = CLI_EXIT.failed;\n }\n}\n\n/** The real world: real streams, real env, the real SDK. */\nexport function createDefaultIo(): CliIo {\n return {\n stdout: process.stdout,\n stderr: process.stderr,\n stdin: process.stdin,\n env: process.env,\n cwd: process.cwd(),\n cacheDir: join(tmpdir(), \"facturas-cli\"),\n now: () => new Date(),\n copyToClipboard: (text) =>\n copyToClipboard(text, {\n env: process.env,\n platform: process.platform,\n }),\n createClient: (options) => createArcaClient(options),\n createAuth: (config: ArcaClientConfig) => createWsaaAuthModule({ config }),\n };\n}\n\n/** Node reports parse failures in English; the CLI only speaks castellano. */\nfunction describeParseError(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n const unknownOption = /Unknown option '([^']+)'/.exec(message)?.[1];\n if (unknownOption !== undefined) {\n return `Opción desconocida: ${unknownOption}`;\n }\n const missingValue = /Option '([^']+)' argument missing/.exec(message)?.[1];\n if (missingValue !== undefined) {\n return `Falta el valor de ${missingValue}`;\n }\n return \"Argumentos inválidos.\";\n}\n\nfunction isCommand(value: string | undefined): value is Command {\n return COMMANDS.includes(value as Command);\n}\n\nfunction toInitFlags(\n values: Record<string, string | boolean | undefined>\n): InitFlags {\n return {\n ...text(values, \"cuit\", \"cuit\"),\n ...text(values, \"env\", \"env\"),\n ...text(values, \"name\", \"name\"),\n ...text(values, \"org\", \"org\"),\n ...text(values, \"dir\", \"dir\"),\n ...(values.force === true ? { force: true } : {}),\n ...(values[\"no-clipboard\"] === true ? { noClipboard: true } : {}),\n ...(values[\"no-paste\"] === true ? { noPaste: true } : {}),\n };\n}\n\nfunction toCertFlags(\n values: Record<string, string | boolean | undefined>\n): CertFlags {\n return {\n ...text(values, \"env\", \"env\"),\n ...text(values, \"dir\", \"dir\"),\n ...(values.force === true ? { force: true } : {}),\n };\n}\n\nfunction toCheckFlags(\n values: Record<string, string | boolean | undefined>,\n salesPoint: number | undefined\n): CheckFlags {\n return {\n ...text(values, \"cert\", \"cert\"),\n ...text(values, \"key\", \"key\"),\n ...text(values, \"cuit\", \"taxId\"),\n ...text(values, \"env\", \"env\"),\n ...text(values, \"dir\", \"dir\"),\n ...(salesPoint === undefined ? {} : { salesPoint }),\n ...(values[\"no-cache\"] === true ? { noCache: true } : {}),\n };\n}\n\nfunction toIssueFlags(\n values: Record<string, string | boolean | undefined>,\n shared: CheckFlags\n): IssueFlags {\n return { ...shared, ...text(values, \"issuer\", \"issuer\") };\n}\n\nfunction text<TKey extends string>(\n values: Record<string, string | boolean | undefined>,\n from: string,\n to: TKey\n): Partial<Record<TKey, string>> {\n const value = values[from];\n return typeof value === \"string\"\n ? ({ [to]: value } as Record<TKey, string>)\n : {};\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport type { ArcaEnvironment } from \"../internal/types\";\nimport {\n type CertificateFacts,\n privateKeyMatchesCertificate,\n readCertificateFacts,\n readCsrTaxId,\n} from \"./csr\";\nimport {\n certificateFileName,\n DISCOVERY_ORDER,\n privateKeyFileName,\n toEnvironment,\n} from \"./discover\";\nimport { CLI_EXIT, type CliIo, type CliWriter } from \"./output\";\nimport { askBlock, isInteractive } from \"./prompt\";\n\n/**\n * The certificate ARCA gives back, taken by paste. In homologación there is no\n * download —the PEM only exists in the browser— so the alternative to this is\n * the user opening an editor for a file they do not have yet.\n */\n\nconst BEGIN = \"-----BEGIN CERTIFICATE-----\";\nconst END = \"-----END CERTIFICATE-----\";\nconst PROMPT = \"> \";\n/** Three pastes before the CLI stops asking and says how to do it by hand. */\nconst PASTE_ATTEMPTS = 3;\nconst NOT_A_CERTIFICATE = [\n \"Eso no parece un certificado PEM. Tiene que ir de\",\n `${BEGIN} a ${END}.`,\n];\n\nexport type CertFlags = {\n env?: string;\n dir?: string;\n force?: boolean;\n};\n\n/** How a paste ended. Only `saved` wrote a file. */\nexport type PasteOutcome = \"saved\" | \"cancelled\" | \"exhausted\" | \"refused\";\n\nexport type PasteRequest = {\n /** What to say before the first prompt. Empty when there is no terminal. */\n intro: string[];\n certificatePath: string;\n certificateName: string;\n keyName: string;\n privateKeyPem: string;\n /** The CUIT the certificate has to be for, when the CLI knows it. */\n taxId?: string;\n};\n\n/**\n * Asks for the certificate, checks it against the key that is already on disk\n * and writes it. Refuses without writing when the certificate belongs to\n * another CUIT or to another key: both mean the paste came from the wrong tab,\n * and a saved file would fail later, in WSAA, with a worse message.\n */\nexport async function pasteCertificate(\n io: CliIo,\n writer: CliWriter,\n request: PasteRequest\n): Promise<PasteOutcome> {\n const interactive = isInteractive(io);\n if (request.intro.length > 0) {\n writer.blank();\n for (const line of request.intro) {\n writer.line(line);\n }\n writer.blank();\n }\n\n for (let attempt = 1; attempt <= PASTE_ATTEMPTS; attempt += 1) {\n // Sequential by nature: each try is an answer to the previous one.\n const lines = await askBlock(\n io,\n interactive ? PROMPT : \"\",\n (line) => line === END\n );\n if (lines === undefined) {\n return \"cancelled\";\n }\n\n const pem = toCertificatePem(lines);\n const facts = readFacts(pem);\n if (facts === undefined) {\n for (const line of NOT_A_CERTIFICATE) {\n io.stderr.write(`${line}\\n`);\n }\n if (interactive && attempt < PASTE_ATTEMPTS) {\n writer.blank();\n }\n continue;\n }\n\n const refusal = refuse(pem, facts, request);\n if (refusal !== undefined) {\n io.stderr.write(`${refusal}\\n`);\n return \"refused\";\n }\n\n writeFileSync(request.certificatePath, pem);\n writer.ok(\n request.certificateName,\n `certificado guardado, vence ${isoDate(facts.notAfter)}`\n );\n return \"saved\";\n }\n return \"exhausted\";\n}\n\n/** The line `init` and `cert` both print when nobody pasted anything. */\nexport function writeManualHint(\n writer: CliWriter,\n certificateName: string\n): void {\n writer.blank();\n writer.line(\n `Cuando tengas el certificado, guardalo acá como ${certificateName},`\n );\n writer.line(\"o pegalo con npx facturas cert, y corré:\");\n writer.blank();\n writer.command(\"npx facturas check\");\n}\n\n/** Reads the certificate that pairs with a key already in the directory. */\nexport async function runCert(\n io: CliIo,\n flags: CertFlags,\n writer: CliWriter\n): Promise<number> {\n const directory = isAbsolute(flags.dir ?? \"\")\n ? (flags.dir as string)\n : resolve(io.cwd, flags.dir ?? \".\");\n\n const asked = flags.env?.trim().toLowerCase();\n const environment =\n asked === undefined || asked === \"\" ? undefined : toEnvironment(asked);\n if (asked !== undefined && asked !== \"\" && environment === undefined) {\n io.stderr.write(\"Falta el entorno. Pasá --env test o --env production.\\n\");\n return CLI_EXIT.usage;\n }\n\n const found = findKeys(directory, environment);\n if (found.length > 1) {\n io.stderr.write(\n `Están ${found.map((candidate) => candidate.keyName).join(\" y \")} en este directorio\\n`\n );\n io.stderr.write(\n \"y no sé cuál querés. Elegí con --env test o --env production.\\n\"\n );\n return CLI_EXIT.failed;\n }\n\n const [target] = found;\n if (target === undefined) {\n const names = (environment === undefined ? DISCOVERY_ORDER : [environment])\n .map((candidate) => privateKeyFileName(candidate))\n .join(\" ni \");\n io.stderr.write(`No encontré ${names} en este directorio.\\n`);\n io.stderr.write(\"Generá la clave y el CSR con npx facturas init.\\n\");\n return CLI_EXIT.failed;\n }\n const certificatePath = resolve(directory, target.certificateName);\n if (existsSync(certificatePath) && flags.force !== true) {\n io.stderr.write(\n `Ya existe ${target.certificateName}. Usá --force para sobrescribir.\\n`\n );\n return CLI_EXIT.failed;\n }\n\n const taxId = readCsrTaxIdOf(directory, target.environment);\n const outcome = await pasteCertificate(io, writer, {\n intro: isInteractive(io)\n ? [\n \"Pegá el certificado que te dio ARCA. Termina solo al ver\",\n `${END}. Ctrl-C para salir.`,\n ]\n : [],\n certificatePath,\n certificateName: target.certificateName,\n keyName: target.keyName,\n privateKeyPem: readFileSync(resolve(directory, target.keyName), \"utf8\"),\n ...(taxId === undefined ? {} : { taxId }),\n });\n\n if (outcome === \"saved\") {\n writer.blank();\n writer.dim(\"Después:\");\n writer.blank();\n writer.command(\"npx facturas check\");\n return CLI_EXIT.ok;\n }\n if (outcome === \"cancelled\") {\n writer.blank();\n writer.line(\"Cuando lo tengas, volvé a correr npx facturas cert, o\");\n writer.line(`guardalo acá como ${target.certificateName}.`);\n return CLI_EXIT.ok;\n }\n if (outcome === \"exhausted\") {\n writeManualHint(writer, target.certificateName);\n }\n return CLI_EXIT.failed;\n}\n\ntype KeyCandidate = {\n environment: ArcaEnvironment;\n keyName: string;\n certificateName: string;\n};\n\n/** The keys `init` left in the directory, in the order `check` looks for them. */\nfunction findKeys(\n directory: string,\n environment: ArcaEnvironment | undefined\n): KeyCandidate[] {\n return (environment === undefined ? DISCOVERY_ORDER : [environment])\n .map((candidate) => ({\n environment: candidate,\n keyName: privateKeyFileName(candidate),\n certificateName: certificateFileName(candidate),\n }))\n .filter((candidate) => existsSync(resolve(directory, candidate.keyName)));\n}\n\n/** The CUIT of the CSR next to the key, when it is still there and readable. */\nfunction readCsrTaxIdOf(\n directory: string,\n environment: ArcaEnvironment\n): string | undefined {\n const path = resolve(directory, `arca-${environment}.csr`);\n if (!existsSync(path)) {\n return undefined;\n }\n try {\n return readCsrTaxId(readFileSync(path, \"utf8\"));\n } catch {\n return undefined;\n }\n}\n\n/** The pasted lines as a PEM file: nothing before BEGIN, one trailing newline. */\nfunction toCertificatePem(lines: string[]): string {\n const start = lines.indexOf(BEGIN);\n const body = start === -1 ? lines : lines.slice(start);\n return `${body.join(\"\\n\")}\\n`;\n}\n\nfunction readFacts(pem: string): CertificateFacts | undefined {\n try {\n return readCertificateFacts(pem);\n } catch {\n return undefined;\n }\n}\n\n/** Why this certificate cannot be saved next to this key, if it cannot. */\nfunction refuse(\n pem: string,\n facts: CertificateFacts,\n request: PasteRequest\n): string | undefined {\n if (\n request.taxId !== undefined &&\n facts.taxId !== undefined &&\n facts.taxId !== request.taxId\n ) {\n return `El certificado es de otro CUIT: ${facts.taxId}.`;\n }\n let matches: boolean;\n try {\n matches = privateKeyMatchesCertificate(pem, request.privateKeyPem);\n } catch {\n return `No pude leer ${request.keyName} como clave PEM.`;\n }\n return matches\n ? undefined\n : `El certificado no corresponde a ${request.keyName}. ¿Subiste otro CSR?`;\n}\n\nfunction isoDate(value: Date): string {\n return value.toISOString().slice(0, 10);\n}\n","import forge from \"node-forge\";\n\nconst RSA_MODULUS_BITS = 2048;\nconst RSA_PUBLIC_EXPONENT = 0x01_00_01;\n/** How ARCA writes the CUIT in the subject, with a literal space after `CUIT`. */\nconst SUBJECT_TAX_ID = /^CUIT\\s+(\\d{11})$/;\n\n/** The distinguished name ARCA expects on a certificate signing request. */\nexport type ArcaCsrSubject = {\n /** 11-digit CUIT. Goes to `serialNumber` as `CUIT <cuit>`. */\n taxId: string;\n /** Alias for the certificate. Goes to `CN`. */\n commonName: string;\n /** Organization. Goes to `O`; defaults to the CUIT when the caller has none. */\n organization: string;\n};\n\n/** An unencrypted PKCS#8 private key and the PKCS#10 request that pairs with it. */\nexport type ArcaCsrMaterial = {\n privateKeyPem: string;\n csrPem: string;\n};\n\n/** What a certificate says about itself, with no credential in sight. */\nexport type CertificateFacts = {\n notBefore: Date;\n notAfter: Date;\n /** The CUIT in `serialNumber`, when ARCA wrote one there. */\n taxId?: string;\n};\n\n/** Builds the subject in the order ARCA's manual writes it: C, O, CN, serialNumber. */\nexport function buildArcaCsrSubject(\n subject: ArcaCsrSubject\n): forge.pki.CertificateField[] {\n return [\n { name: \"countryName\", value: \"AR\" },\n { name: \"organizationName\", value: subject.organization },\n { name: \"commonName\", value: subject.commonName },\n { name: \"serialNumber\", value: `CUIT ${subject.taxId}` },\n ];\n}\n\n/** Generates an RSA 2048 key and the CSR to upload in ARCA. Pure and offline. */\nexport function createArcaCsrMaterial(\n subject: ArcaCsrSubject\n): ArcaCsrMaterial {\n const keyPair = forge.pki.rsa.generateKeyPair({\n bits: RSA_MODULUS_BITS,\n e: RSA_PUBLIC_EXPONENT,\n });\n const privateKeyPem = toPkcs8Pem(keyPair.privateKey);\n const request = forge.pki.createCertificationRequest();\n request.publicKey = keyPair.publicKey;\n request.setSubject(buildArcaCsrSubject(subject));\n request.sign(keyPair.privateKey, forge.md.sha256.create());\n\n return {\n privateKeyPem,\n csrPem: forge.pki.certificationRequestToPem(request),\n };\n}\n\n/** Serializes an RSA private key as an unencrypted PKCS#8 PEM. */\nexport function toPkcs8Pem(privateKey: forge.pki.rsa.PrivateKey): string {\n return forge.pki.privateKeyInfoToPem(\n forge.pki.wrapRsaPrivateKey(forge.pki.privateKeyToAsn1(privateKey))\n );\n}\n\n/**\n * Reads the validity window and the CUIT of a certificate PEM. Throws on\n * anything that is not a certificate. ARCA issues against the CSR this CLI\n * writes, so the CUIT comes back in `serialNumber` as `CUIT <11 dígitos>`;\n * a certificate from somewhere else may carry nothing there.\n */\nexport function readCertificateFacts(certificatePem: string): CertificateFacts {\n const certificate = forge.pki.certificateFromPem(certificatePem);\n const taxId = readSubjectTaxId(certificate);\n return {\n notBefore: certificate.validity.notBefore,\n notAfter: certificate.validity.notAfter,\n ...(taxId === undefined ? {} : { taxId }),\n };\n}\n\n/**\n * The CUIT in the subject of a certificate signing request. `init` writes it\n * there, so `cert` can read back which CUIT a directory belongs to without\n * asking. Throws on anything that is not a PKCS#10 request.\n */\nexport function readCsrTaxId(csrPem: string): string | undefined {\n return readSubjectTaxId(forge.pki.certificationRequestFromPem(csrPem));\n}\n\n/** Both a certificate and a request keep the CUIT in the same subject field. */\nfunction readSubjectTaxId(source: {\n subject: { getField(options: { name: string }): unknown };\n}): string | undefined {\n const field = source.subject.getField({ name: \"serialNumber\" }) as {\n value?: unknown;\n } | null;\n if (typeof field?.value !== \"string\") {\n return undefined;\n }\n return SUBJECT_TAX_ID.exec(field.value.trim())?.[1];\n}\n\n/**\n * True when the private key is the one the certificate was issued for: same\n * RSA modulus and same public exponent. Throws when either PEM does not parse.\n */\nexport function privateKeyMatchesCertificate(\n certificatePem: string,\n privateKeyPem: string\n): boolean {\n const certificate = forge.pki.certificateFromPem(certificatePem);\n const privateKey = forge.pki.privateKeyFromPem(privateKeyPem);\n const certificateKey = certificate.publicKey as forge.pki.rsa.PublicKey;\n\n if (certificateKey?.n === undefined || certificateKey.e === undefined) {\n return false;\n }\n\n return (\n certificateKey.n.compareTo(privateKey.n) === 0 &&\n certificateKey.e.compareTo(privateKey.e) === 0\n );\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { ARCA_ENVIRONMENTS } from \"../config\";\nimport type { ArcaEnvironment } from \"../internal/types\";\n\n/**\n * The credential files `init` writes, found where the user is standing. This\n * is a convenience of the CLI and nothing else: `createArcaClient()` keeps\n * reading the environment, and the SDK never looks at the filesystem.\n */\n\n/** Homologación first: it is where everyone starts. */\nexport const DISCOVERY_ORDER: readonly ArcaEnvironment[] = [\n \"test\",\n \"production\",\n];\n\n/** The environment a written answer names, or `undefined` when it names none. */\nexport function toEnvironment(value: string): ArcaEnvironment | undefined {\n return ARCA_ENVIRONMENTS.includes(value as ArcaEnvironment)\n ? (value as ArcaEnvironment)\n : undefined;\n}\n\n/** The certificate `init` tells the user to save for that environment. */\nexport function certificateFileName(environment: ArcaEnvironment): string {\n return `arca-${environment}.crt`;\n}\n\n/** The private key `init` writes for that environment. */\nexport function privateKeyFileName(environment: ArcaEnvironment): string {\n return `arca-${environment}.key`;\n}\n\n/** A complete pair and the conventional file names for its environment. */\nexport type DiscoveredCredentials = {\n environment: ArcaEnvironment;\n certificateFile: string;\n keyFile: string;\n certificatePem: string;\n privateKeyPem: string;\n};\n\n/**\n * What the directory holds. `ambiguous` means both environments are there and\n * only the user can say which one they meant; `incomplete` means half a pair,\n * which is what a directory looks like between `init` and ARCA's answer.\n */\nexport type CredentialDiscovery =\n | { kind: \"none\" }\n | { kind: \"found\"; credentials: DiscoveredCredentials }\n | { kind: \"ambiguous\"; files: string[] }\n | {\n kind: \"incomplete\";\n /** The file that is there, and the one that is not. */\n present: string;\n missing: string;\n /** Which half is missing, because the fix for each is different. */\n missingKind: \"certificate\" | \"key\";\n };\n\n/**\n * Looks for `arca-<entorno>.crt` and `arca-<entorno>.key` in one directory.\n * With an environment already chosen, only that pair is considered.\n * Supplied PEMs complete a pair and take precedence over its files.\n *\n * @throws When a file exists but cannot be read.\n */\nexport function discoverCredentials(\n directory: string,\n environment?: ArcaEnvironment,\n supplied: { certificatePem?: string; privateKeyPem?: string } = {}\n): CredentialDiscovery {\n const candidates = (\n environment === undefined ? DISCOVERY_ORDER : [environment]\n ).map((candidate) => {\n const certificateFile = certificateFileName(candidate);\n const keyFile = privateKeyFileName(candidate);\n return {\n environment: candidate,\n certificateFile,\n keyFile,\n hasCertificate: existsSync(resolve(directory, certificateFile)),\n hasKey: existsSync(resolve(directory, keyFile)),\n };\n });\n\n const complete = candidates.filter(\n (candidate) =>\n (candidate.hasCertificate || supplied.certificatePem) &&\n (candidate.hasKey || supplied.privateKeyPem)\n );\n if (complete.length > 1) {\n return {\n kind: \"ambiguous\",\n files: complete.map((candidate) =>\n supplied.certificatePem ? candidate.keyFile : candidate.certificateFile\n ),\n };\n }\n\n const [pair] = complete;\n if (pair !== undefined) {\n return {\n kind: \"found\",\n credentials: {\n environment: pair.environment,\n certificateFile: pair.certificateFile,\n keyFile: pair.keyFile,\n certificatePem:\n supplied.certificatePem || read(directory, pair.certificateFile),\n privateKeyPem: supplied.privateKeyPem || read(directory, pair.keyFile),\n },\n };\n }\n\n const half = candidates.find(\n (candidate) => candidate.hasCertificate || candidate.hasKey\n );\n if (half === undefined) {\n return { kind: \"none\" };\n }\n return half.hasCertificate\n ? {\n kind: \"incomplete\",\n present: half.certificateFile,\n missing: half.keyFile,\n missingKind: \"key\",\n }\n : {\n kind: \"incomplete\",\n present: half.keyFile,\n missing: half.certificateFile,\n missingKind: \"certificate\",\n };\n}\n\nfunction read(directory: string, file: string): string {\n return readFileSync(resolve(directory, file), \"utf8\").trim();\n}\n","import type { ArcaClient } from \"../client\";\nimport type { ArcaClientConfig, ArcaClientOptions } from \"../internal/types\";\nimport type { WsaaAuthModule } from \"../wsaa\";\n\n/** Minimal writable surface the CLI needs. Tests pass a string collector. */\nexport type CliOutputStream = {\n write(chunk: string): void;\n isTTY?: boolean;\n};\n\n/** Minimal readable surface the CLI needs for interactive prompts. */\nexport type CliInputStream = NodeJS.ReadableStream & { isTTY?: boolean };\n\n/** Everything the CLI touches outside itself. Injected so tests stay offline. */\nexport type CliIo = {\n stdout: CliOutputStream;\n stderr: CliOutputStream;\n stdin: CliInputStream;\n env: Record<string, string | undefined>;\n cwd: string;\n /** Where the WSAA ticket is cached between runs. Never holds anything else. */\n cacheDir: string;\n now(): Date;\n /**\n * Puts text in the system clipboard, answering whether it got there. Nothing\n * else in the CLI touches the clipboard, and a `false` is never an error.\n */\n copyToClipboard(text: string): Promise<boolean>;\n createClient(options: ArcaClientOptions): ArcaClient;\n createAuth(config: ArcaClientConfig): WsaaAuthModule;\n};\n\n/** 0 all good, 1 something ARCA-side is wrong, 2 the command was wrong. */\nexport const CLI_EXIT = {\n ok: 0,\n failed: 1,\n usage: 2,\n} as const;\n\nconst GREEN = \"\\u001B[32m\";\nconst RED = \"\\u001B[31m\";\nconst YELLOW = \"\\u001B[33m\";\nconst CYAN = \"\\u001B[36m\";\nconst BOLD = \"\\u001B[1m\";\nconst DIM = \"\\u001B[2m\";\nconst RESET = \"\\u001B[0m\";\n\n/** Column where a layer detail starts, so the marks line up like a shell. */\nconst LABEL_WIDTH = 22;\nconst INDENT = \" \";\n\n/**\n * Wraps text in one ANSI sequence, or returns it untouched when color is off.\n * The whole CLI paints through this, so `--no-color` output is the same text\n * minus the escapes and nothing else.\n */\nexport type CliPainter = {\n green(text: string): string;\n red(text: string): string;\n yellow(text: string): string;\n cyan(text: string): string;\n bold(text: string): string;\n dim(text: string): string;\n};\n\n/** The painter for a stream whose color was already decided. */\nexport function createPainter(color: boolean): CliPainter {\n const paint = (code: string) => (text: string) =>\n color ? `${code}${text}${RESET}` : text;\n return {\n green: paint(GREEN),\n red: paint(RED),\n yellow: paint(YELLOW),\n cyan: paint(CYAN),\n bold: paint(BOLD),\n dim: paint(DIM),\n };\n}\n\n/** One line per fact. Colors land on the mark and nowhere else. */\nexport type CliWriter = {\n /** The painter this writer prints with, for text painted before it gets here. */\n painter: CliPainter;\n ok(label: string, detail?: string): void;\n fail(label: string, detail?: string): void;\n warn(label: string, detail?: string): void;\n /** An indented continuation line: a diagnosis, a fix or one sales point. */\n note(text: string): void;\n line(text: string): void;\n /** A whole line in dim: an aside the reader can skip without losing the plot. */\n dim(text: string): void;\n /** An indented shell line: a dim `$` and the command in cyan. */\n command(text: string): void;\n blank(): void;\n json(value: unknown): void;\n};\n\n/**\n * ANSI is on only for a TTY without `NO_COLOR` and without `--no-color`.\n * Either of those two turns it off, whatever else says. `FORCE_COLOR` turns it\n * on without a TTY, for CI logs that do render escapes; `FORCE_COLOR=0` is the\n * conventional way of saying no.\n */\nexport function shouldUseColor(\n stream: CliOutputStream,\n env: Record<string, string | undefined>,\n noColorFlag = false\n): boolean {\n if (noColorFlag || env.NO_COLOR !== undefined) {\n return false;\n }\n if (env.FORCE_COLOR !== undefined) {\n return env.FORCE_COLOR !== \"0\";\n }\n return stream.isTTY === true;\n}\n\nexport function createWriter(\n stream: CliOutputStream,\n options: { color: boolean }\n): CliWriter {\n const painter = createPainter(options.color);\n\n const mark = (symbol: string, label: string, detail?: string) => {\n const body =\n detail === undefined ? label : `${label.padEnd(LABEL_WIDTH)} ${detail}`;\n stream.write(`${symbol} ${body}\\n`);\n };\n\n return {\n painter,\n ok(label, detail) {\n mark(painter.green(\"✓\"), label, detail);\n },\n fail(label, detail) {\n mark(painter.red(\"✗\"), label, detail);\n },\n warn(label, detail) {\n mark(painter.yellow(\"!\"), label, detail);\n },\n note(text) {\n stream.write(`${INDENT}${text}\\n`);\n },\n line(text) {\n stream.write(`${text}\\n`);\n },\n dim(text) {\n stream.write(`${painter.dim(text)}\\n`);\n },\n command(text) {\n stream.write(`${INDENT}${painter.dim(\"$\")} ${painter.cyan(text)}\\n`);\n },\n blank() {\n stream.write(\"\\n\");\n },\n json(value) {\n stream.write(`${JSON.stringify(value, null, 2)}\\n`);\n },\n };\n}\n","import { createInterface } from \"node:readline/promises\";\nimport type { CliIo } from \"./output\";\n\n/**\n * True when the CLI may ask a question. Without a TTY on stdin every missing\n * value has to arrive as a flag, so scripts and CI fail fast instead of hanging.\n */\nexport function isInteractive(io: CliIo): boolean {\n return io.stdin.isTTY === true;\n}\n\n/** Asks one question and returns the trimmed answer. Only call on a TTY. */\nexport async function ask(io: CliIo, question: string): Promise<string> {\n const rl = createInterface({\n input: io.stdin,\n output: io.stdout as NodeJS.WritableStream,\n });\n try {\n const answer = await rl.question(question);\n return answer.trim();\n } finally {\n rl.close();\n }\n}\n\n/**\n * Reads a pasted block: every line from the first non-blank one up to the one\n * `endsAt` recognizes, trimmed. `undefined` means the user backed out —Ctrl-C\n * on a terminal, or the end of the input anywhere else— and never a half block\n * the caller could mistake for a complete one.\n */\nexport async function askBlock(\n io: CliIo,\n prompt: string,\n endsAt: (line: string) => boolean\n): Promise<string[] | undefined> {\n io.stdout.write(prompt);\n const rl = createInterface({\n input: io.stdin,\n output: io.stdout as NodeJS.WritableStream,\n });\n const lines: string[] = [];\n let complete = false;\n // Without this listener readline lets Ctrl-C kill the process; with it, the\n // paste the user gave up on is just an empty answer.\n rl.on(\"SIGINT\", () => rl.close());\n try {\n for await (const raw of rl) {\n const line = raw.trim();\n if (lines.length === 0 && line === \"\") {\n continue;\n }\n lines.push(line);\n if (endsAt(line)) {\n complete = true;\n break;\n }\n }\n } finally {\n rl.close();\n }\n return complete ? lines : undefined;\n}\n","import { readFileSync } from \"node:fs\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport type { ArcaClient } from \"../client\";\nimport {\n ARCA_WSAA_CONFIG,\n assertArcaClientConfig,\n discoverArcaClientConfig,\n} from \"../config\";\nimport {\n ArcaConfigurationError,\n ArcaServiceError,\n ArcaSoapFaultError,\n isArcaAuthenticationError,\n} from \"../errors\";\nimport type {\n ArcaAuthCredentials,\n ArcaClientConfig,\n ArcaEnvironment,\n ArcaWsaaSessionStore,\n} from \"../internal/types\";\nimport type { WsfeSalesPoint } from \"../services/wsfe\";\nimport { createFileStore } from \"../store/file\";\nimport { createWsaaStoreAdapter } from \"../wsaa/store-adapter\";\nimport { privateKeyMatchesCertificate, readCertificateFacts } from \"./csr\";\nimport { describeTaxIdProblem, normalizeTaxId, TAX_ID_FIX } from \"./cuit\";\nimport {\n type CliDiagnosis,\n describeUnknownError,\n diagnose,\n diagnoseAuthenticationReason,\n diagnoseWsaaFaultCode,\n findSoapFault,\n findTransportError,\n} from \"./diagnose\";\nimport {\n type CredentialDiscovery,\n type DiscoveredCredentials,\n discoverCredentials,\n} from \"./discover\";\nimport { CLI_EXIT, type CliIo, type CliWriter } from \"./output\";\n\nconst EXPIRY_WARNING_DAYS = 30;\nconst EMPTY_IN_TEST_WARNING =\n \"en homologación ARCA suele no informarlos; probá igual con issue\";\nconst MILLISECONDS_PER_DAY = 86_400_000;\n\n/** The five layers, in the order ARCA breaks them. */\nexport type CliLayerName =\n | \"config\"\n | \"certificate\"\n | \"wsaa\"\n | \"wsfe\"\n | \"salesPoints\";\n\nconst LAYER_LABELS: Record<CliLayerName, string> = {\n config: \"configuración\",\n certificate: \"certificado y clave\",\n wsaa: \"WSAA\",\n wsfe: \"WSFE\",\n salesPoints: \"puntos de venta\",\n};\n\nexport type CliLayerReport = {\n name: CliLayerName;\n ok: boolean;\n detail?: string;\n expiresAt?: string;\n code?: string;\n reason?: string;\n diagnosis?: string;\n fix?: string;\n warning?: string;\n};\n\nexport type CliSalesPointReport = {\n number: number;\n blocked: boolean;\n system?: string;\n};\n\n/** The whole `check` result. Layers never reached are absent, not false. */\nexport type CliCheckReport = {\n ok: boolean;\n environment?: ArcaEnvironment;\n taxId?: string;\n layers: CliLayerReport[];\n salesPoints?: CliSalesPointReport[];\n};\n\nexport type CheckFlags = {\n cert?: string;\n key?: string;\n taxId?: string;\n env?: string;\n /** Where to look for `arca-<entorno>.crt` and `.key`. Defaults to the cwd. */\n dir?: string;\n salesPoint?: number;\n /** Skips the ticket cache: one forced login, kept in memory only. */\n noCache?: boolean;\n};\n\n/**\n * WSFE's `PtoVta` is an integer from 1 to 99999. Anything a number only starts\n * with —`3foo`, `3.5`, `1e2`— is a typo, not a sales point: parsing it would\n * silently work on a different one than the person typed.\n */\nconst SALES_POINT_MIN = 1;\nconst SALES_POINT_MAX = 99_999;\n\n/** The sales point a string names, or `undefined` when it names none. */\nexport function parseSalesPoint(value: string): number | undefined {\n if (!/^\\d+$/.test(value)) {\n return undefined;\n }\n const parsed = Number(value);\n return parsed >= SALES_POINT_MIN && parsed <= SALES_POINT_MAX\n ? parsed\n : undefined;\n}\n\n/** Why that string is not a sales point, in the words the CLI uses. */\nexport function describeSalesPointProblem(value: string): string {\n const reason = /^\\d+$/.test(value)\n ? `Tiene que estar entre ${SALES_POINT_MIN} y ${SALES_POINT_MAX}`\n : \"Tiene que ser un número entero\";\n return `Punto de venta inválido: ${value}. ${reason}, por ejemplo --sales-point 3.`;\n}\n\ntype TicketCache = {\n sessionStore: ArcaWsaaSessionStore;\n /** True once a stored ticket was handed back instead of a fresh login. */\n wasReused(): boolean;\n};\n\n/** The report plus the client the passing layers built, for `issue` to reuse. */\nexport type CliCheckResult = {\n report: CliCheckReport;\n client?: ArcaClient;\n};\n\n/** Runs `check` and prints it. Never writes to ARCA. */\nexport async function runCheck(\n io: CliIo,\n flags: CheckFlags,\n writer: CliWriter,\n json: boolean\n): Promise<number> {\n const { report } = await runCheckLayers(io, flags);\n if (json) {\n writer.json(report);\n } else {\n writeCheckReport(writer, report);\n }\n return report.ok ? CLI_EXIT.ok : CLI_EXIT.failed;\n}\n\n/** Runs the layers in order and stops at the first failure. */\nexport async function runCheckLayers(\n io: CliIo,\n flags: CheckFlags\n): Promise<CliCheckResult> {\n const layers: CliLayerReport[] = [];\n const resolved = resolveConfigLayer(io, flags);\n layers.push(resolved.layer);\n if (!(resolved.layer.ok && resolved.config)) {\n return { report: { ok: false, layers } };\n }\n\n const config = resolved.config;\n const report: CliCheckReport = {\n ok: false,\n environment: config.environment,\n taxId: config.taxId,\n layers,\n };\n\n const certificate = checkCertificate(config, io.now());\n layers.push(certificate);\n if (!certificate.ok) {\n return { report };\n }\n\n const cache =\n flags.noCache === true ? undefined : createTicketCache(io.cacheDir, config);\n const wsaa = await checkWsaa(io, config, cache);\n layers.push(wsaa.layer);\n if (!(wsaa.layer.ok && wsaa.credentials)) {\n return { report };\n }\n\n // WSFE reuses the ticket layer 3 obtained: a second login would collide with\n // it as coe.alreadyAuthenticated.\n const client = io.createClient({\n ...config,\n wsaaSessionStore:\n cache?.sessionStore ?? createEphemeralSessionStore(wsaa.credentials),\n });\n const wsfe = await checkWsfe(client);\n layers.push(wsfe.layer);\n if (!wsfe.layer.ok) {\n return { report, client };\n }\n\n const salesPoints = wsfe.salesPoints ?? [];\n report.salesPoints = salesPoints.map(toSalesPointReport);\n const layer = checkSalesPoints(\n report.salesPoints,\n config.environment,\n flags.salesPoint\n );\n layers.push(layer);\n report.ok = layer.ok;\n return { report, client };\n}\n\n/** Renders the report the way a shell would: one line per fact. */\nexport function writeCheckReport(\n writer: CliWriter,\n report: CliCheckReport\n): void {\n for (const layer of report.layers) {\n const label = LAYER_LABELS[layer.name];\n if (layer.ok) {\n writer.ok(label, layer.detail);\n } else {\n writer.fail(label);\n if (layer.diagnosis !== undefined) {\n writer.note(layer.diagnosis);\n }\n if (layer.fix !== undefined) {\n writer.note(layer.fix);\n }\n }\n if (layer.name === \"salesPoints\") {\n for (const point of report.salesPoints ?? []) {\n writer.note(describeSalesPoint(point));\n }\n }\n if (layer.warning !== undefined) {\n writer.warn(label, layer.warning);\n }\n }\n}\n\n/**\n * The environment `check` would use, found without touching ARCA: the flag,\n * the variable, or the name of the pair sitting in the directory. `issue` asks\n * first, because it refuses to write anywhere but homologación. `undefined`\n * means nothing said so yet; the layers will name whatever is wrong.\n */\nexport function resolveCheckEnvironment(\n io: CliIo,\n flags: CheckFlags\n): string | undefined {\n const chosen =\n flags.env?.trim().toLowerCase() || io.env.ARCA_ENVIRONMENT?.trim();\n if (chosen) {\n return chosen;\n }\n try {\n const { discovery } = resolveCredentials(io, flags);\n return discovery.kind === \"found\"\n ? discovery.credentials.environment\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction resolveCredentials(\n io: CliIo,\n flags: CheckFlags,\n environment?: ArcaEnvironment\n) {\n const certificatePem = readPem(io, flags.cert, io.env.ARCA_CERTIFICATE_PEM);\n const privateKeyPem = readPem(io, flags.key, io.env.ARCA_PRIVATE_KEY_PEM);\n const discovery: CredentialDiscovery =\n certificatePem && privateKeyPem\n ? { kind: \"none\" }\n : discoverCredentials(resolveDirectory(io, flags.dir), environment, {\n certificatePem,\n privateKeyPem,\n });\n return { certificatePem, privateKeyPem, discovery };\n}\n\n/**\n * Where every value came from. Flags win, then the environment variables, then\n * the files `init` left in the directory. The parts the line does not need are\n * absent: when the environment comes from the file name, saying it twice adds\n * nothing.\n */\ntype ConfigOrigin = {\n credentials?: string;\n taxId: string;\n environment?: string;\n};\n\nfunction resolveConfigLayer(\n io: CliIo,\n flags: CheckFlags\n): { layer: CliLayerReport; config?: ArcaClientConfig } {\n const chosenEnvironment =\n flags.env?.trim().toLowerCase() || io.env.ARCA_ENVIRONMENT?.trim();\n\n let certificatePem: string | undefined;\n let privateKeyPem: string | undefined;\n let discovery: CredentialDiscovery;\n try {\n ({ certificatePem, privateKeyPem, discovery } = resolveCredentials(\n io,\n flags,\n toEnvironment(chosenEnvironment)\n ));\n } catch (error) {\n const unknown = describeUnknownError(error);\n return {\n layer: failedLayer(\n \"config\",\n { diagnosis: unknown.diagnosis },\n unknown.code\n ),\n };\n }\n\n const failure = describeDiscoveryFailure(discovery);\n if (failure) {\n return { layer: failedLayer(\"config\", failure) };\n }\n\n const found = discovery.kind === \"found\" ? discovery.credentials : undefined;\n const certificate = certificatePem || found?.certificatePem;\n const privateKey = privateKeyPem || found?.privateKeyPem;\n\n const taxId = resolveTaxId(io, flags, certificate);\n if (\"layer\" in taxId) {\n return { layer: taxId.layer };\n }\n\n const environment = chosenEnvironment || found?.environment;\n if (!environment) {\n return { layer: failedLayer(\"config\", diagnose(\"config.environment\")) };\n }\n if (!(certificate && privateKey)) {\n return { layer: failedLayer(\"config\", diagnose(\"config.pem\")) };\n }\n\n try {\n const config = discoverArcaClientConfig({\n taxId: taxId.taxId,\n certificatePem: certificate,\n privateKeyPem: privateKey,\n environment: environment as ArcaEnvironment,\n });\n assertArcaClientConfig(config);\n return {\n layer: {\n name: \"config\",\n ok: true,\n detail: describeSources({\n ...describeCredentialSource(flags, found, certificatePem),\n taxId: taxId.source,\n ...describeEnvironmentSource(io, flags, config.environment),\n }),\n },\n config,\n };\n } catch (error) {\n return { layer: failedLayer(\"config\", toConfigDiagnosis(error)) };\n }\n}\n\n/**\n * The CUIT, in order: the flag, the variable, and last the `serialNumber` ARCA\n * wrote in the certificate. Without any of the three there is nothing to ask\n * ARCA about.\n */\nfunction resolveTaxId(\n io: CliIo,\n flags: CheckFlags,\n certificatePem: string | undefined\n): { taxId: string; source: string } | { layer: CliLayerReport } {\n const given = flags.taxId?.trim() || io.env.ARCA_TAX_ID?.trim();\n if (given) {\n const problem = describeTaxIdProblem(given);\n if (problem !== undefined) {\n return {\n layer: failedLayer(\"config\", { diagnosis: problem, fix: TAX_ID_FIX }),\n };\n }\n return {\n taxId: normalizeTaxId(given),\n source: flags.taxId?.trim() ? \"--cuit\" : \"ARCA_TAX_ID\",\n };\n }\n if (certificatePem === undefined) {\n return { layer: failedLayer(\"config\", diagnose(\"config.taxId\")) };\n }\n\n const fromCertificate = readCertificateTaxId(certificatePem);\n if (fromCertificate === undefined) {\n return { layer: failedLayer(\"config\", diagnose(\"config.taxIdUnknown\")) };\n }\n return {\n taxId: fromCertificate,\n source: `CUIT ${fromCertificate} del certificado`,\n };\n}\n\n/** The CUIT in the certificate, or nothing when the PEM does not even parse. */\nfunction readCertificateTaxId(certificatePem: string): string | undefined {\n try {\n return readCertificateFacts(certificatePem).taxId;\n } catch {\n // Layer 2 is where a PEM that does not parse gets its own row.\n return undefined;\n }\n}\n\nfunction describeDiscoveryFailure(\n discovery: CredentialDiscovery\n): CliDiagnosis | undefined {\n if (discovery.kind === \"ambiguous\") {\n return diagnose(\"config.files.ambiguous\", {\n files: discovery.files.join(\" y \"),\n });\n }\n if (discovery.kind === \"incomplete\") {\n return diagnose(\n discovery.missingKind === \"certificate\"\n ? \"config.files.missingCertificate\"\n : \"config.files.missingKey\",\n { file: discovery.present, missingFile: discovery.missing }\n );\n }\n return undefined;\n}\n\nfunction resolveDirectory(io: CliIo, directory: string | undefined): string {\n return isAbsolute(directory ?? \"\")\n ? (directory as string)\n : resolve(io.cwd, directory ?? \".\");\n}\n\nfunction toEnvironment(value: string | undefined): ArcaEnvironment | undefined {\n return value === \"test\" || value === \"production\" ? value : undefined;\n}\n\nfunction readPem(\n io: CliIo,\n file: string | undefined,\n fromEnv: string | undefined\n): string | undefined {\n if (file === undefined || file === \"\") {\n return fromEnv?.trim() || undefined;\n }\n const path = isAbsolute(file) ? file : resolve(io.cwd, file);\n return readFileSync(path, \"utf8\").trim();\n}\n\n/**\n * Only a file is worth naming. PEMs that came from the environment are the\n * default and stay unsaid, which keeps the old line for the old setup.\n */\nfunction describeCredentialSource(\n flags: CheckFlags,\n found: DiscoveredCredentials | undefined,\n suppliedCertificate: string | undefined\n): { credentials?: string } {\n const named = [\n ...(flags.cert?.trim() ? [\"--cert\"] : []),\n ...(flags.key?.trim() ? [\"--key\"] : []),\n ];\n if (found !== undefined) {\n const file = suppliedCertificate ? found.keyFile : found.certificateFile;\n named.push(`${file} en este directorio`);\n }\n return named.length === 0 ? {} : { credentials: named.join(\" y \") };\n}\n\n/** The file name already says the environment, so nothing is added for it. */\nfunction describeEnvironmentSource(\n io: CliIo,\n flags: CheckFlags,\n environment: ArcaEnvironment\n): { environment?: string } {\n if (flags.env?.trim()) {\n return { environment: `--env=${environment}` };\n }\n if (io.env.ARCA_ENVIRONMENT?.trim()) {\n return { environment: `ARCA_ENVIRONMENT=${environment}` };\n }\n return {};\n}\n\nfunction describeSources(origin: ConfigOrigin): string {\n return [origin.credentials, origin.taxId, origin.environment]\n .filter((part): part is string => part !== undefined)\n .join(\", \");\n}\n\nfunction toConfigDiagnosis(error: unknown): CliDiagnosis {\n if (!(error instanceof ArcaConfigurationError)) {\n return { diagnosis: describeUnknownError(error).diagnosis };\n }\n if (error.message.includes(\"taxId\")) {\n return diagnose(\"config.taxId\");\n }\n if (error.message.includes(\"environment\")) {\n return diagnose(\"config.environment\");\n }\n if (\n error.message.includes(\"certificatePem\") ||\n error.message.includes(\"privateKeyPem\") ||\n error.message.includes(\"Encrypted private keys\")\n ) {\n return diagnose(\"cert.invalid\");\n }\n return { diagnosis: error.message };\n}\n\nfunction checkCertificate(config: ArcaClientConfig, now: Date): CliLayerReport {\n let facts: ReturnType<typeof readCertificateFacts>;\n let matches: boolean;\n try {\n facts = readCertificateFacts(config.certificatePem);\n matches = privateKeyMatchesCertificate(\n config.certificatePem,\n config.privateKeyPem\n );\n } catch {\n return failedLayer(\"certificate\", diagnose(\"cert.invalid\"));\n }\n\n // A certificate for another CUIT is a misconfiguration, not something ARCA\n // forgives: WSAA answers for whoever the certificate belongs to.\n if (facts.taxId !== undefined && facts.taxId !== config.taxId) {\n return failedLayer(\n \"certificate\",\n diagnose(\"cert.taxIdMismatch\", {\n certificateTaxId: facts.taxId,\n taxId: config.taxId,\n })\n );\n }\n\n const expiresAt = toIsoDate(facts.notAfter);\n if (facts.notAfter.getTime() <= now.getTime()) {\n return failedLayer(\n \"certificate\",\n diagnose(\"cert.expired\", { date: expiresAt })\n );\n }\n if (!matches) {\n return failedLayer(\"certificate\", diagnose(\"cert.mismatch\"));\n }\n\n const daysLeft = Math.floor(\n (facts.notAfter.getTime() - now.getTime()) / MILLISECONDS_PER_DAY\n );\n return {\n name: \"certificate\",\n ok: true,\n detail: `coinciden, vence ${expiresAt}`,\n expiresAt,\n ...(daysLeft < EXPIRY_WARNING_DAYS\n ? { warning: `vence en ${daysLeft} ${daysLeft === 1 ? \"día\" : \"días\"}` }\n : {}),\n };\n}\n\nasync function checkWsaa(\n io: CliIo,\n config: ArcaClientConfig,\n cache: TicketCache | undefined\n): Promise<{ layer: CliLayerReport; credentials?: ArcaAuthCredentials }> {\n try {\n const auth = io.createAuth({\n ...config,\n ...(cache === undefined ? {} : { wsaaSessionStore: cache.sessionStore }),\n });\n const credentials = await auth.login(\"wsfe\", {\n forceRefresh: cache === undefined,\n });\n return {\n layer: {\n name: \"wsaa\",\n ok: true,\n detail:\n cache?.wasReused() === true ? \"ticket vigente\" : \"ticket obtenido\",\n },\n credentials,\n };\n } catch (error) {\n return { layer: toWsaaFailure(error, config.environment) };\n }\n}\n\nfunction toWsaaFailure(\n error: unknown,\n environment: ArcaEnvironment\n): CliLayerReport {\n const fault = findSoapFault(error);\n const key = diagnoseWsaaFaultCode(fault?.faultCode);\n if (key !== undefined) {\n return failedLayer(\"wsaa\", diagnose(key), fault?.code);\n }\n\n const transport = findTransportError(error);\n if (transport) {\n const host = new URL(ARCA_WSAA_CONFIG.endpoint[environment]).host;\n return failedLayer(\n \"wsaa\",\n diagnose(\"wsaa.transport\", { host }),\n transport.code\n );\n }\n\n const unknown = describeUnknownError(error);\n return failedLayer(\"wsaa\", { diagnosis: unknown.diagnosis }, unknown.code);\n}\n\nasync function checkWsfe(\n client: ArcaClient\n): Promise<{ layer: CliLayerReport; salesPoints?: WsfeSalesPoint[] }> {\n try {\n const status = await client.wsfe.getServerStatus();\n const down = [\n [\"appServer\", status.appServer],\n [\"dbServer\", status.dbServer],\n [\"authServer\", status.authServer],\n ].filter(([, value]) => value.toUpperCase() !== \"OK\");\n if (down.length > 0) {\n const message = down\n .map(([name, value]) => `${name}=${value}`)\n .join(\", \");\n return {\n layer: failedLayer(\"wsfe\", diagnose(\"wsfe.serviceError\", { message })),\n };\n }\n\n const salesPoints = await client.wsfe.getSalesPoints();\n return {\n layer: { name: \"wsfe\", ok: true, detail: \"servidor ok\" },\n salesPoints,\n };\n } catch (error) {\n return { layer: toWsfeFailure(error) };\n }\n}\n\nfunction toWsfeFailure(error: unknown): CliLayerReport {\n if (isArcaAuthenticationError(error)) {\n return {\n ...failedLayer(\n \"wsfe\",\n diagnoseAuthenticationReason(error.reason),\n error.code\n ),\n reason: error.reason,\n };\n }\n if (\n error instanceof ArcaServiceError ||\n error instanceof ArcaSoapFaultError\n ) {\n return failedLayer(\n \"wsfe\",\n diagnose(\"wsfe.serviceError\", { message: error.message }),\n error.code\n );\n }\n const unknown = describeUnknownError(error);\n return failedLayer(\"wsfe\", { diagnosis: unknown.diagnosis }, unknown.code);\n}\n\nfunction checkSalesPoints(\n points: CliSalesPointReport[],\n environment: ArcaEnvironment,\n requested: number | undefined\n): CliLayerReport {\n if (requested !== undefined) {\n const found = points.find((point) => point.number === requested);\n if (!found) {\n // Homologación often reports no points at all for ones that work.\n if (points.length === 0 && environment === \"test\") {\n return {\n name: \"salesPoints\",\n ok: true,\n detail: `${requested} (no informado)`,\n warning: EMPTY_IN_TEST_WARNING,\n };\n }\n return failedLayer(\n \"salesPoints\",\n diagnose(\"salesPoint.missing\", { salesPoint: requested })\n );\n }\n if (found.blocked) {\n return failedLayer(\n \"salesPoints\",\n diagnose(\"salesPoint.blocked\", { salesPoint: requested })\n );\n }\n return {\n name: \"salesPoints\",\n ok: true,\n detail: describeSalesPoint(found),\n };\n }\n\n if (points.length === 0) {\n // In homologación ARCA often reports nothing for points that work. In\n // production an empty list is the whole answer: no invoice can be issued.\n if (environment === \"test\") {\n return {\n name: \"salesPoints\",\n ok: true,\n detail: \"ninguno informado\",\n warning: EMPTY_IN_TEST_WARNING,\n };\n }\n return failedLayer(\"salesPoints\", diagnose(\"salesPoint.none\"));\n }\n\n return {\n name: \"salesPoints\",\n ok: true,\n detail: `${points.length} ${points.length === 1 ? \"informado\" : \"informados\"}`,\n };\n}\n\n/**\n * The WSAA ticket, kept in the system temp directory so `check` and `issue`\n * can be run again inside the 12 hours ARCA keeps it valid. The file store\n * creates the directory 0700 and writes 0600. Nothing else is ever stored.\n */\nfunction createTicketCache(\n directory: string,\n config: ArcaClientConfig\n): TicketCache {\n const store = createWsaaStoreAdapter(createFileStore(directory), config);\n let reused = false;\n const remove = store.delete?.bind(store);\n return {\n sessionStore: {\n get: async (key) => {\n const credentials = await store.get(key);\n if (credentials) {\n reused = true;\n }\n return credentials;\n },\n set: (key, credentials) => store.set(key, credentials),\n ...(remove === undefined ? {} : { delete: remove }),\n },\n wasReused: () => reused,\n };\n}\n\n/** Keeps the ticket from the WSAA layer in memory so WSFE reuses it. */\nfunction createEphemeralSessionStore(\n credentials: ArcaAuthCredentials\n): ArcaWsaaSessionStore {\n return {\n get: () => Promise.resolve(credentials),\n set: () => Promise.resolve(),\n };\n}\n\nfunction toSalesPointReport(point: WsfeSalesPoint): CliSalesPointReport {\n return {\n number: point.number,\n blocked: point.blocked,\n ...(point.emissionType === undefined ? {} : { system: point.emissionType }),\n };\n}\n\nfunction describeSalesPoint(point: CliSalesPointReport): string {\n const state = point.blocked ? \"bloqueado\" : \"habilitado\";\n return point.system === undefined\n ? `${point.number} (${state})`\n : `${point.number} (${state}, ${point.system})`;\n}\n\nfunction failedLayer(\n name: CliLayerName,\n row: CliDiagnosis,\n code?: string\n): CliLayerReport {\n return {\n name,\n ok: false,\n diagnosis: row.diagnosis,\n ...(row.fix === undefined ? {} : { fix: row.fix }),\n ...(code === undefined ? {} : { code }),\n };\n}\n\nfunction toIsoDate(value: Date): string {\n return value.toISOString().slice(0, 10);\n}\n","/**\n * CUIT validation for the CLI, so a wrong number is named as wrong instead of\n * being reported as missing. The SDK keeps its own, looser rule: it only asks\n * for eleven digits, and it is ARCA that decides whether a CUIT exists.\n */\n\n/** The weights ARCA applies to the first ten digits, in order. */\nconst CHECK_DIGIT_WEIGHTS = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2] as const;\nconst TAX_ID_LENGTH = 11;\nconst MODULUS = 11;\nconst SEPARATORS = /[\\s.-]/g;\n\n/** What to do about a CUIT the CLI rejected. One line, same everywhere. */\nexport const TAX_ID_FIX =\n \"Son 11 dígitos y el último es el verificador; podés escribirlo con guiones.\";\n\n/** Drops the separators people type: `20-12345678-6` and `20 12345678 6`. */\nexport function normalizeTaxId(raw: string): string {\n return raw.trim().replace(SEPARATORS, \"\");\n}\n\n/**\n * Why this CUIT cannot be used, or `undefined` when it is a well-formed one.\n * An empty value is reported as eleven digits missing; callers that can tell\n * \"missing\" from \"wrong\" should check for emptiness before calling.\n */\nexport function describeTaxIdProblem(raw: string): string | undefined {\n const digits = normalizeTaxId(raw);\n if (!/^\\d*$/.test(digits)) {\n return `CUIT inválido: ${raw.trim()} tiene caracteres que no son dígitos.`;\n }\n if (digits.length !== TAX_ID_LENGTH) {\n const plural = digits.length === 1 ? \"dígito\" : \"dígitos\";\n return `CUIT inválido: ${digits} tiene ${digits.length} ${plural} y necesita ${TAX_ID_LENGTH}.`;\n }\n if (!hasValidCheckDigit(digits)) {\n return `CUIT inválido: ${digits} no pasa el dígito verificador.`;\n }\n return undefined;\n}\n\n/** True when the CUIT is well formed. Says nothing about it existing in ARCA. */\nexport function isValidTaxId(raw: string): boolean {\n return describeTaxIdProblem(raw) === undefined;\n}\n\n/**\n * The módulo 11 rule ARCA uses: the first ten digits weighted by\n * `5 4 3 2 7 6 5 4 3 2`, and the check digit is `11 - (suma % 11)`. A\n * remainder of 0 leaves 11, which is written as 0. A remainder of 1 would\n * need a 10, which is not a digit: ARCA issues those numbers under another\n * prefix (23) instead, so no real CUIT has one.\n */\nfunction hasValidCheckDigit(digits: string): boolean {\n const sum = CHECK_DIGIT_WEIGHTS.reduce(\n (total, weight, index) => total + weight * Number(digits[index]),\n 0\n );\n const remainder = sum % MODULUS;\n if (remainder === 1) {\n return false;\n }\n const expected = remainder === 0 ? 0 : MODULUS - remainder;\n return expected === Number(digits[TAX_ID_LENGTH - 1]);\n}\n","import type { ArcaEnvironment } from \"../internal/types\";\nimport type { CliPainter } from \"./output\";\n\n/**\n * ARCA page, menu, field and button names, in one table so a rename is one\n * edit here and one in `docs/cli.md`. Verified against the official references\n * linked from `docs/habilitacion-arca.md`: the WSASS user manual\n * (`ws/WSASS/html/`), `WSASS_como_adherirse.pdf`, `WSAA.ObtenerCertificado.pdf`\n * and `ADMINREL.DelegarWS.pdf`.\n */\nexport const ARCA_PAGES = {\n login: \"https://auth.afip.gob.ar/contribuyente_/login.xhtml\",\n wsassService: \"WSASS - Autogestión Certificados Homologación\",\n wsassNewCertificate: \"Nuevo Certificado\",\n wsassNewCertificateButton: \"Crear DN y Obtener Certificado\",\n wsassAuthorizeService: \"Crear autorización a servicio\",\n wsassAuthorizeButton: \"Crear Autorización de Acceso\",\n wsassDnField: \"Nombre simbólico del DN\",\n wsassCsrField: \"Solicitud de certificado\",\n wsassAuthorizeDnField: \"Nombre simbólico del DN a autorizar\",\n wsassRepresentedField: \"CUIT representado\",\n wsassServiceField: \"Servicio al que desea acceder\",\n wsfeService: \"wsfe - Facturación Electrónica\",\n certificates: \"Administración de Certificados Digitales\",\n certificatesAddAlias: \"Agregar alias\",\n relationships: \"Administrador de Relaciones\",\n relationshipsNew: \"Nueva Relación\",\n relationshipsAdhere: \"Adherir Servicio\",\n relationshipsPath: \"Nueva Relación → Webservices → Facturación Electrónica\",\n salesPoints: \"Administración de Puntos de Venta y Domicilios\",\n salesPointsSystem: \"RECE para aplicativo y Web Services\",\n salesPointsSystemMonotributo:\n \"Factura Electrónica – Monotributo – Web Services\",\n} as const;\n\n/** One printed line of the plan. Every one of them is an instruction. */\nexport type ArcaPlanLine = { text: string };\n\n/** The whole block `init` prints after the files: a heading and its steps. */\nexport type ArcaPlan = { heading: string; lines: ArcaPlanLine[] };\n\n/** What the plan needs from the run: the alias and the file names in play. */\nexport type ArcaPlanContext = {\n alias: string;\n taxId: string;\n csrName: string;\n certificateName: string;\n /** True when the CSR is already in the clipboard and step 3 is one paste. */\n clipboard: boolean;\n /** The CSR itself, printed in step 3 when there is no clipboard. */\n csrPem: string;\n /** True when the CLI is about to ask for the certificate right below. */\n paste: boolean;\n};\n\nconst STEP_INDENT = \" \";\n/** Where a wrapped step line starts: under the step text, not under its number. */\nconst WRAP_INDENT = \" \";\nconst FIELD_INDENT = \" \";\n/** Spaces between the widest label of a step and its value column. */\nconst COLUMN_GAP = 3;\n\n/** One `label value` row, plus the block that hangs under it, if any. */\ntype Field = { label: string; value: string; lines?: string[] };\n\n/**\n * The ARCA steps for one environment, as a single linear list. `init` already\n * knows the environment, so the other one is noise: nothing here mentions it.\n */\nexport function buildArcaPlan(\n environment: ArcaEnvironment,\n context: ArcaPlanContext,\n painter: CliPainter\n): ArcaPlan {\n return environment === \"test\"\n ? buildTestPlan(context, painter)\n : buildProductionPlan(context, painter);\n}\n\nfunction buildTestPlan(\n context: ArcaPlanContext,\n painter: CliPainter\n): ArcaPlan {\n const name = (text: string) => painter.bold(`\"${text}\"`);\n return {\n heading: \"Listo. Ahora en ARCA, para homologación:\",\n lines: [\n ...step(1, [\"Entrá con clave fiscal en\", ARCA_PAGES.login]),\n ...step(2, [\n `Abrí ${name(ARCA_PAGES.wsassService)} en Mis Servicios.`,\n `Si no está, agregalo en ${ARCA_PAGES.relationships} → ${ARCA_PAGES.relationshipsAdhere}`,\n \"→ ARCA → Servicios Interactivos → WSASS, y volvé a entrar. Va con tu\",\n \"clave fiscal de persona física, nivel 2 o superior: no es delegable.\",\n ]),\n ...step(\n 3,\n [`En el menú, ${name(ARCA_PAGES.wsassNewCertificate)}:`],\n [\n { label: ARCA_PAGES.wsassDnField, value: context.alias },\n csrField(context),\n ],\n [`Apretá ${name(ARCA_PAGES.wsassNewCertificateButton)}.`]\n ),\n ...step(4, [\n \"El certificado sale en el cuadro de resultado, de\",\n \"-----BEGIN CERTIFICATE----- a -----END CERTIFICATE-----.\",\n context.paste\n ? \"Copialo entero y pegalo acá abajo.\"\n : `Copialo entero y guardalo acá como ${context.certificateName}.`,\n ]),\n ...step(\n 5,\n [`En el menú, ${name(ARCA_PAGES.wsassAuthorizeService)}:`],\n [\n { label: ARCA_PAGES.wsassAuthorizeDnField, value: context.alias },\n { label: ARCA_PAGES.wsassRepresentedField, value: context.taxId },\n {\n label: ARCA_PAGES.wsassServiceField,\n value: ARCA_PAGES.wsfeService,\n },\n ],\n [`Apretá ${name(ARCA_PAGES.wsassAuthorizeButton)}.`]\n ),\n ],\n };\n}\n\nfunction buildProductionPlan(\n context: ArcaPlanContext,\n painter: CliPainter\n): ArcaPlan {\n const name = (text: string) => painter.bold(`\"${text}\"`);\n return {\n heading: \"Listo. Ahora en ARCA, para producción:\",\n lines: [\n ...step(1, [\"Entrá con clave fiscal en\", ARCA_PAGES.login]),\n ...step(2, [\n `Abrí ${name(ARCA_PAGES.certificates)} en Mis Servicios.`,\n `Si no está, agregalo en ${ARCA_PAGES.relationships} → ${ARCA_PAGES.relationshipsNew}`,\n \"→ BUSCAR → Servicios Interactivos → Administración de Certificados\",\n \"Digitales → Confirmar, y volvé a entrar.\",\n ]),\n ...step(\n 3,\n [`Apretá ${name(ARCA_PAGES.certificatesAddAlias)}:`],\n [\n { label: \"Alias\", value: context.alias },\n { label: \"Seleccionar archivo\", value: context.csrName },\n ],\n [`Apretá ${name(ARCA_PAGES.certificatesAddAlias)} para subirlo.`]\n ),\n ...step(4, [\n `En la lista, entrá con ${name(\"Ver\")} y usá el icono ${name(\"Descargar\")}`,\n \"para bajar el certificado (archivo CRT).\",\n context.paste\n ? `Guardalo acá como ${context.certificateName}, o abrilo y pegalo abajo.`\n : `Guardalo acá como ${context.certificateName}.`,\n ]),\n ...step(\n 5,\n [\n `Volvé a ${ARCA_PAGES.relationships}, ${name(ARCA_PAGES.relationshipsNew)}:`,\n ],\n [\n {\n label: \"Servicio\",\n value: \"BUSCAR → Webservices → Facturación Electrónica\",\n },\n {\n label: \"Representante\",\n value: `BUSCAR → el computador fiscal ${context.alias}`,\n },\n ],\n [\n `Apretá ${name(\"Confirmar\")}, revisá y volvé a apretar ${name(\"Confirmar\")}.`,\n ]\n ),\n ],\n };\n}\n\n/**\n * One numbered step: its text, an optional aligned `label value` block and\n * the lines that come after it.\n */\nfunction step(\n number: number,\n text: string[],\n fields: Field[] = [],\n after: string[] = []\n): ArcaPlanLine[] {\n const [first, ...rest] = text;\n const lines: ArcaPlanLine[] = [{ text: `${STEP_INDENT}${number}. ${first}` }];\n for (const line of rest) {\n lines.push({ text: `${WRAP_INDENT}${line}` });\n }\n const width = columnWidth(fields);\n for (const field of fields) {\n const padding = \" \".repeat(width - field.label.length);\n lines.push({\n text: `${FIELD_INDENT}${field.label}:${padding}${field.value}`,\n });\n for (const line of field.lines ?? []) {\n lines.push({ text: `${FIELD_INDENT}${line}` });\n }\n }\n for (const line of after) {\n lines.push({ text: `${WRAP_INDENT}${line}` });\n }\n return lines;\n}\n\n/**\n * The CSR row of step 3. With the clipboard it is one word; without it the\n * whole request goes under the field, because a terminal is the only place\n * the user can copy it from without opening an editor.\n */\nfunction csrField(context: ArcaPlanContext): Field {\n if (context.clipboard) {\n return {\n label: ARCA_PAGES.wsassCsrField,\n value: \"pegá (ya está en tu portapapeles)\",\n };\n }\n return {\n label: ARCA_PAGES.wsassCsrField,\n value: \"copiá esto entero:\",\n lines: context.csrPem\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\"),\n };\n}\n\n/** Where the values start, counting the colon the labels get when printed. */\nfunction columnWidth(fields: Field[]): number {\n const widest = fields.reduce(\n (longest, field) => Math.max(longest, field.label.length),\n 0\n );\n return widest + COLUMN_GAP;\n}\n","import {\n type ArcaAuthenticationReason,\n ArcaSoapFaultError,\n ArcaTransportError,\n toArcaSafeErrorMetadata,\n} from \"../errors\";\nimport { ARCA_PAGES } from \"./arca-steps\";\n\n/** Keys of {@link CLI_DIAGNOSES}. One row of the published diagnosis table. */\nexport type CliDiagnosisKey =\n | \"config.taxId\"\n | \"config.taxIdUnknown\"\n | \"config.environment\"\n | \"config.pem\"\n | \"config.files.ambiguous\"\n | \"config.files.missingCertificate\"\n | \"config.files.missingKey\"\n | \"cert.invalid\"\n | \"cert.taxIdMismatch\"\n | \"cert.mismatch\"\n | \"cert.expired\"\n | \"wsaa.certExpired\"\n | \"wsaa.certUntrusted\"\n | \"wsaa.signInvalid\"\n | \"wsaa.notAuthorized\"\n | \"wsaa.alreadyAuthenticated\"\n | \"wsaa.clockSkew\"\n | \"wsaa.transport\"\n | \"wsfe.missing_relationship\"\n | \"wsfe.unauthorized_computer\"\n | \"wsfe.invalid_token\"\n | \"wsfe.authentication_rejected\"\n | \"wsfe.serviceError\"\n | \"salesPoint.missing\"\n | \"salesPoint.none\"\n | \"salesPoint.blocked\";\n\n/** What went wrong, and the page and action that fix it. Both in castellano. */\nexport type CliDiagnosis = {\n diagnosis: string;\n fix?: string;\n};\n\n/** Values substituted into the `{placeholders}` of a row. */\nexport type CliDiagnosisValues = {\n certificateTaxId?: string;\n date?: string;\n file?: string;\n files?: string;\n host?: string;\n message?: string;\n missingFile?: string;\n salesPoint?: number;\n taxId?: string;\n};\n\n/**\n * The diagnosis table. Every failure the CLI can name has exactly one row, and\n * every row is unit-tested. Nothing here interpolates a PEM, a token or a sign.\n */\nexport const CLI_DIAGNOSES: Record<CliDiagnosisKey, CliDiagnosis> = {\n \"config.taxId\": {\n diagnosis: \"Falta el CUIT.\",\n fix: \"export ARCA_TAX_ID=20123456786\",\n },\n \"config.taxIdUnknown\": {\n diagnosis: \"El certificado no dice de qué CUIT es.\",\n fix: \"Pasá --cuit 20123456786 o definí ARCA_TAX_ID.\",\n },\n \"config.environment\": {\n diagnosis: \"Falta el entorno.\",\n fix: \"export ARCA_ENVIRONMENT=test\",\n },\n \"config.pem\": {\n diagnosis: \"Falta el certificado o la clave.\",\n fix: \"Guardá arca-<entorno>.crt y arca-<entorno>.key acá, o pasá --cert y --key, o definí las variables ARCA_*_PEM.\",\n },\n \"config.files.ambiguous\": {\n diagnosis: \"Están {files} en este directorio y no sé cuál querés.\",\n fix: \"Elegí con --env test o --env production.\",\n },\n \"config.files.missingCertificate\": {\n diagnosis: \"Está {file} pero falta {missingFile}.\",\n fix: \"Descargá el certificado de ARCA y guardalo acá como {missingFile}.\",\n },\n \"config.files.missingKey\": {\n diagnosis: \"Está {file} pero falta {missingFile}.\",\n fix: \"Poné acá la clave con la que generaste el CSR, o pasá --key.\",\n },\n \"cert.invalid\": {\n diagnosis: \"El archivo no es un PEM válido.\",\n fix: \"Revisá que copiaste el bloque completo, con BEGIN y END.\",\n },\n \"cert.taxIdMismatch\": {\n diagnosis:\n \"El certificado es del CUIT {certificateTaxId} y el configurado es {taxId}.\",\n fix: \"Usá el certificado de ese CUIT, o corregí --cuit o ARCA_TAX_ID.\",\n },\n \"cert.mismatch\": {\n diagnosis: \"La clave privada no corresponde a este certificado.\",\n fix: \"Usá la clave con la que generaste el CSR (arca-<entorno>.key).\",\n },\n \"cert.expired\": {\n diagnosis: \"El certificado venció el {date}.\",\n fix: \"Generá un CSR nuevo con npx facturas init y renovalo en ARCA.\",\n },\n \"wsaa.certExpired\": {\n diagnosis: \"El certificado venció.\",\n fix: \"Generá un CSR nuevo con npx facturas init y renovalo en ARCA.\",\n },\n \"wsaa.certUntrusted\": {\n diagnosis: \"ARCA no reconoce este certificado en este entorno.\",\n fix: \"Homologación y producción tienen certificados propios; revisá ARCA_ENVIRONMENT.\",\n },\n \"wsaa.signInvalid\": {\n diagnosis: \"La firma del pedido no es válida.\",\n fix: \"La clave no corresponde al certificado, o el PEM está truncado.\",\n },\n \"wsaa.notAuthorized\": {\n diagnosis: \"El certificado no está autorizado para wsfe.\",\n fix: `${ARCA_PAGES.wsassService} → ${ARCA_PAGES.wsassAuthorizeService} (homologación) / ${ARCA_PAGES.relationships} (producción).`,\n },\n \"wsaa.alreadyAuthenticated\": {\n diagnosis: \"Ya hay un ticket vigente para este certificado.\",\n fix: \"Otro proceso o máquina tiene el ticket vigente. Esperá hasta 12 horas, o corré check desde donde lo pediste.\",\n },\n \"wsaa.clockSkew\": {\n diagnosis: \"La hora de tu máquina difiere de la de ARCA.\",\n fix: \"Sincronizá el reloj (NTP) y volvé a probar.\",\n },\n \"wsaa.transport\": {\n diagnosis: \"No se pudo conectar con {host}.\",\n fix: \"Revisá red, proxy o firewall; ARCA homologación suele caerse los fines de semana.\",\n },\n \"wsfe.missing_relationship\": {\n diagnosis:\n \"El certificado no tiene la relación con Facturación Electrónica.\",\n fix: `${ARCA_PAGES.relationships} → ${ARCA_PAGES.relationshipsPath}.`,\n },\n \"wsfe.unauthorized_computer\": {\n diagnosis: \"El certificado o computador no está autorizado.\",\n fix: \"Verificá que el alias esté asociado al servicio en este entorno.\",\n },\n \"wsfe.invalid_token\": {\n diagnosis: \"El ticket fue rechazado.\",\n fix: \"Volvé a ejecutar check; si persiste, revisá el reloj.\",\n },\n \"wsfe.authentication_rejected\": {\n diagnosis: \"ARCA denegó el acceso al servicio.\",\n fix: \"Revisá entorno y relación del certificado.\",\n },\n \"wsfe.serviceError\": {\n diagnosis: \"ARCA respondió con un error: {message}.\",\n },\n \"salesPoint.missing\": {\n diagnosis:\n \"El punto de venta {salesPoint} no está habilitado para web services.\",\n fix: `ARCA → ${ARCA_PAGES.salesPoints} → Nuevo → el sistema de web services de tu condición (\"${ARCA_PAGES.salesPointsSystem}\" para responsable inscripto).`,\n },\n \"salesPoint.none\": {\n diagnosis: \"ARCA no informa ningún punto de venta para web services.\",\n fix: `ARCA → ${ARCA_PAGES.salesPoints} → Nuevo → \"${ARCA_PAGES.salesPointsSystem}\" para responsable inscripto, \"${ARCA_PAGES.salesPointsSystemMonotributo}\" para monotributo.`,\n },\n \"salesPoint.blocked\": {\n diagnosis: \"El punto de venta {salesPoint} está bloqueado.\",\n fix: \"Revisalo en ARCA.\",\n },\n};\n\n/** Resolves one row and fills its `{placeholders}`. */\nexport function diagnose(\n key: CliDiagnosisKey,\n values: CliDiagnosisValues = {}\n): CliDiagnosis {\n const row = CLI_DIAGNOSES[key];\n return {\n diagnosis: fill(row.diagnosis, values),\n ...(row.fix === undefined ? {} : { fix: fill(row.fix, values) }),\n };\n}\n\n/** Maps `ArcaAuthenticationError.reason` to its row. */\nexport function diagnoseAuthenticationReason(\n reason: ArcaAuthenticationReason\n): CliDiagnosis {\n return diagnose(`wsfe.${reason}`);\n}\n\nconst WSAA_FAULT_ROWS: Readonly<Record<string, CliDiagnosisKey>> = {\n \"cms.cert.expired\": \"wsaa.certExpired\",\n \"cms.cert.untrusted\": \"wsaa.certUntrusted\",\n \"cms.cert.invalid\": \"wsaa.certUntrusted\",\n \"cms.cert.notfound\": \"wsaa.certUntrusted\",\n \"cms.bad\": \"wsaa.signInvalid\",\n \"cms.sign.invalid\": \"wsaa.signInvalid\",\n \"coe.notauthorized\": \"wsaa.notAuthorized\",\n \"coe.alreadyauthenticated\": \"wsaa.alreadyAuthenticated\",\n \"xml.generationtime.invalid\": \"wsaa.clockSkew\",\n \"xml.expirationtime.invalid\": \"wsaa.clockSkew\",\n \"xml.expirationtime.expired\": \"wsaa.clockSkew\",\n};\n\n/**\n * Maps a WSAA SOAP fault code to its row. ARCA prefixes the code with a SOAP\n * namespace (`ns1:coe.notAuthorized`), so the prefix is dropped first.\n */\nexport function diagnoseWsaaFaultCode(\n faultCode: string | undefined\n): CliDiagnosisKey | undefined {\n if (faultCode === undefined) {\n return undefined;\n }\n const bare = faultCode.slice(faultCode.indexOf(\":\") + 1).toLowerCase();\n const exact = WSAA_FAULT_ROWS[bare];\n if (exact) {\n return exact;\n }\n return bare.startsWith(\"xml.expirationtime.\") ? \"wsaa.clockSkew\" : undefined;\n}\n\n/** The SOAP fault carried by an error, or by the error the SDK wrapped it in. */\nexport function findSoapFault(error: unknown): ArcaSoapFaultError | undefined {\n if (error instanceof ArcaSoapFaultError) {\n return error;\n }\n const cause = error instanceof Error ? error.cause : undefined;\n return cause instanceof ArcaSoapFaultError ? cause : undefined;\n}\n\n/** The transport failure carried by an error, or by its cause. */\nexport function findTransportError(\n error: unknown\n): ArcaTransportError | undefined {\n if (error instanceof ArcaTransportError) {\n return error;\n }\n const cause = error instanceof Error ? error.cause : undefined;\n return cause instanceof ArcaTransportError ? cause : undefined;\n}\n\n/** Fallback for anything the table does not name. Never prints credentials. */\nexport function describeUnknownError(error: unknown): {\n diagnosis: string;\n code?: string;\n} {\n const safe = toArcaSafeErrorMetadata(error);\n return {\n diagnosis: safe.message,\n ...(safe.code === undefined ? {} : { code: safe.code }),\n };\n}\n\nfunction fill(text: string, values: CliDiagnosisValues): string {\n return text.replace(\n /\\{(certificateTaxId|date|file|files|host|message|missingFile|salesPoint|taxId)\\}/g,\n (match, key) => {\n const value = values[key as keyof CliDiagnosisValues];\n return value === undefined ? match : String(value);\n }\n );\n}\n","import { spawn as spawnProcess } from \"node:child_process\";\n\n/**\n * The system clipboard, through the tool each platform already ships. There is\n * no dependency and no shell: the text goes to the process' stdin, so nothing\n * a CSR contains can ever be read as a command. Every failure —no binary, no\n * display, a non-zero exit, a hang— is the same answer, `false`, and the CLI\n * prints the CSR instead.\n */\n\n/** How long a clipboard tool has to take the text before the CLI moves on. */\nconst TIMEOUT_MS = 2000;\n\ntype ClipboardStdin = {\n write(chunk: string): unknown;\n end(): unknown;\n on(event: \"error\", listener: (error: Error) => void): unknown;\n};\n\n/** The little of a child process this module uses. Tests pass a fake. */\nexport type ClipboardProcess = {\n stdin: ClipboardStdin | null;\n on(event: \"error\", listener: (error: Error) => void): unknown;\n on(event: \"close\", listener: (code: number | null) => void): unknown;\n kill(): unknown;\n};\n\n/** `child_process.spawn`, narrowed to what the clipboard needs. */\nexport type ClipboardSpawn = (\n command: string,\n args: readonly string[]\n) => ClipboardProcess;\n\nexport type ClipboardOptions = {\n spawn?: ClipboardSpawn;\n platform?: string;\n env?: Record<string, string | undefined>;\n /** Only tests pass this. */\n timeoutMs?: number;\n};\n\ntype ClipboardCommand = { command: string; args: string[] };\n\n/**\n * The tools worth trying, in order, for one platform. Empty means \"no\n * clipboard here\": a headless Linux box, an SSH session —where the tool would\n * write to the clipboard of the wrong machine— or an unknown platform.\n */\nexport function clipboardCommands(\n platform: string,\n env: Record<string, string | undefined>\n): ClipboardCommand[] {\n if (env.SSH_CONNECTION !== undefined || env.SSH_TTY !== undefined) {\n return [];\n }\n if (platform === \"darwin\") {\n return [{ command: \"pbcopy\", args: [] }];\n }\n if (platform === \"win32\") {\n return [{ command: \"clip\", args: [] }];\n }\n const commands: ClipboardCommand[] = [];\n if (env.WAYLAND_DISPLAY !== undefined) {\n commands.push({ command: \"wl-copy\", args: [] });\n }\n if (env.DISPLAY !== undefined) {\n commands.push(\n { command: \"xclip\", args: [\"-selection\", \"clipboard\"] },\n { command: \"xsel\", args: [\"--clipboard\", \"--input\"] }\n );\n }\n return commands;\n}\n\n/**\n * Puts `text` in the system clipboard. Never throws and never writes anything\n * to the terminal: the caller decides what to say about `false`.\n */\nexport async function copyToClipboard(\n text: string,\n options: ClipboardOptions = {}\n): Promise<boolean> {\n const spawn =\n options.spawn ??\n ((command, args) =>\n spawnProcess(command, [...args], {\n stdio: [\"pipe\", \"ignore\", \"ignore\"],\n }) as ClipboardProcess);\n const commands = clipboardCommands(\n options.platform ?? process.platform,\n options.env ?? process.env\n );\n\n for (const candidate of commands) {\n // Sequential on purpose: the second tool is the fallback of the first,\n // and running both would put the text in the clipboard twice.\n const copied = await feed(\n spawn,\n candidate,\n text,\n options.timeoutMs ?? TIMEOUT_MS\n );\n if (copied) {\n return true;\n }\n }\n return false;\n}\n\n/** Runs one tool and answers whether it took the text. */\nfunction feed(\n spawn: ClipboardSpawn,\n candidate: ClipboardCommand,\n text: string,\n timeoutMs: number\n): Promise<boolean> {\n return new Promise<boolean>((done) => {\n let settled = false;\n let timer: NodeJS.Timeout | undefined;\n const finish = (copied: boolean) => {\n if (settled) {\n return;\n }\n settled = true;\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n done(copied);\n };\n\n let child: ClipboardProcess;\n try {\n child = spawn(candidate.command, candidate.args);\n } catch {\n finish(false);\n return;\n }\n\n timer = setTimeout(() => {\n child.kill();\n finish(false);\n }, timeoutMs);\n child.on(\"error\", () => finish(false));\n child.on(\"close\", (code) => finish(code === 0));\n\n const stdin = child.stdin;\n if (stdin === null) {\n finish(false);\n return;\n }\n stdin.on(\"error\", () => finish(false));\n try {\n stdin.write(text);\n stdin.end();\n } catch {\n finish(false);\n }\n });\n}\n","import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst MAX_DEPTH = 5;\n\n/**\n * Reads the published version from the nearest `package.json`. Walking up is\n * needed because the bundled `dist/cli.mjs` and `src/cli/version.ts` sit at\n * different depths from the manifest.\n */\nexport function readCliVersion(): string {\n let directory = dirname(fileURLToPath(import.meta.url));\n for (let depth = 0; depth < MAX_DEPTH; depth += 1) {\n try {\n const raw = readFileSync(join(directory, \"package.json\"), \"utf8\");\n const parsed = JSON.parse(raw) as { version?: string };\n if (typeof parsed.version === \"string\") {\n return parsed.version;\n }\n } catch {\n // Keep walking up: bundled output and source sit at different depths.\n }\n directory = dirname(directory);\n }\n return \"0.0.0\";\n}\n","import { createPainter } from \"./output\";\nimport { readCliVersion } from \"./version\";\n\n/** One help page: the root one, or one per command. */\nexport type CliHelpTopic = \"root\" | \"init\" | \"cert\" | \"check\" | \"issue\";\n\ntype HelpRow = { name: string; description?: string };\n\ntype HelpSection = {\n title: string;\n rows: HelpRow[];\n /** Names in bold. Only the command list uses it; flags stay plain. */\n bold?: boolean;\n};\n\ntype HelpPage = {\n /** One line saying what the command does. The root page has none. */\n summary?: string;\n usage: string;\n sections: HelpSection[];\n examples: string[];\n /** What the command writes, caches or touches. Short, never a paragraph. */\n notes?: string[];\n};\n\nconst INDENT = \" \";\n/** Spaces between the widest name of a section and its description column. */\nconst COLUMN_GAP = 3;\n\n/** What each command does, in the words the root page and the docs use. */\nexport const CLI_COMMAND_SUMMARIES = {\n init: \"clave privada y CSR, más los pasos exactos en ARCA\",\n cert: \"pega el certificado que te dio ARCA y lo guarda\",\n check: \"prueba cada capa en orden y nombra la que falla\",\n issue: \"una factura de ARS 1 en homologación, solo a pedido\",\n} as const;\n\nconst HELP_PAGES: Record<CliHelpTopic, HelpPage> = {\n root: {\n usage: \"npx facturas <comando> [opciones]\",\n sections: [\n {\n title: \"Comandos:\",\n bold: true,\n rows: [\n { name: \"init\", description: CLI_COMMAND_SUMMARIES.init },\n { name: \"cert\", description: CLI_COMMAND_SUMMARIES.cert },\n { name: \"check\", description: CLI_COMMAND_SUMMARIES.check },\n { name: \"issue\", description: CLI_COMMAND_SUMMARIES.issue },\n ],\n },\n {\n title: \"Opciones globales:\",\n rows: [\n { name: \"--json\", description: \"salida JSON (check e issue)\" },\n { name: \"--no-color\", description: \"sin colores\" },\n {\n name: \"-h, --help\",\n description: \"ayuda de un comando: npx facturas check --help\",\n },\n { name: \"-v, --version\" },\n ],\n },\n ],\n examples: [\n \"npx facturas init --cuit 20123456786 --env test\",\n \"npx facturas check\",\n \"npx facturas issue --sales-point 3 --issuer monotributo\",\n ],\n },\n init: {\n summary: CLI_COMMAND_SUMMARIES.init,\n usage: \"npx facturas init [opciones]\",\n sections: [\n {\n title: \"Opciones:\",\n rows: [\n {\n name: \"--cuit <cuit>\",\n description: \"CUIT de 11 dígitos, con o sin guiones\",\n },\n {\n name: \"--env <test|production>\",\n description: \"entorno de destino\",\n },\n {\n name: \"--name <alias>\",\n description: \"common name del CSR (por defecto: facturas)\",\n },\n {\n name: \"--org <razón social>\",\n description: \"organización del CSR (por defecto: el CUIT)\",\n },\n {\n name: \"--dir <directorio>\",\n description: \"dónde escribir los archivos (por defecto: el actual)\",\n },\n {\n name: \"--force\",\n description: \"sobrescribe los archivos existentes\",\n },\n {\n name: \"--no-clipboard\",\n description: \"no copia el CSR al portapapeles\",\n },\n {\n name: \"--no-paste\",\n description: \"no pregunta por el certificado al final\",\n },\n { name: \"--no-color\", description: \"sin colores\" },\n { name: \"-h, --help\", description: \"esta ayuda\" },\n ],\n },\n ],\n examples: [\n \"npx facturas init --cuit 20123456786 --env test\",\n \"npx facturas init --cuit 20-12345678-6 --env production --name mi-sistema\",\n ],\n notes: [\n \"Escribe arca-<entorno>.key con permisos 0600 y arca-<entorno>.csr, y\",\n \"nunca escribe en ARCA. En homologación copia el CSR al portapapeles, y\",\n \"si no puede lo imprime para copiarlo de la terminal. Al final pide el\",\n \"certificado y lo guarda como arca-<entorno>.crt; con Ctrl-C, --no-paste\",\n \"o sin terminal, lo guardás vos o lo pegás después con cert. En una\",\n \"terminal pregunta el CUIT y el entorno; sin terminal, --cuit y --env\",\n \"son obligatorios.\",\n ],\n },\n cert: {\n summary: CLI_COMMAND_SUMMARIES.cert,\n usage: \"npx facturas cert [opciones]\",\n sections: [\n {\n title: \"Opciones:\",\n rows: [\n {\n name: \"--env <test|production>\",\n description: \"cuál par usar si están los dos\",\n },\n {\n name: \"--dir <directorio>\",\n description: \"dónde están los archivos (por defecto: el actual)\",\n },\n {\n name: \"--force\",\n description: \"sobrescribe el certificado existente\",\n },\n { name: \"--no-color\", description: \"sin colores\" },\n { name: \"-h, --help\", description: \"esta ayuda\" },\n ],\n },\n ],\n examples: [\n \"npx facturas cert\",\n \"npx facturas cert --env production\",\n \"npx facturas cert --dir credenciales --force\",\n ],\n notes: [\n \"Pegás el certificado que te dio ARCA, de -----BEGIN CERTIFICATE----- a\",\n \"-----END CERTIFICATE-----, y lo guarda como arca-<entorno>.crt junto a\",\n \"la clave que generó init. Antes verifica que sea el certificado de esa\",\n \"clave y de ese CUIT, y si no, no escribe nada. Es lo mismo que init\",\n \"pregunta al final: cert está para cuando lo dejaste para después.\",\n ],\n },\n check: {\n summary: CLI_COMMAND_SUMMARIES.check,\n usage: \"npx facturas check [opciones]\",\n sections: [\n {\n title: \"Opciones:\",\n rows: [\n {\n name: \"--cert <archivo>\",\n description: \"certificado PEM desde un archivo\",\n },\n {\n name: \"--key <archivo>\",\n description: \"clave privada PEM desde un archivo\",\n },\n {\n name: \"--cuit <cuit>\",\n description: \"CUIT, en lugar de ARCA_TAX_ID\",\n },\n {\n name: \"--env <test|production>\",\n description: \"entorno, en lugar de ARCA_ENVIRONMENT\",\n },\n {\n name: \"--dir <directorio>\",\n description: \"dónde buscar los archivos (por defecto: el actual)\",\n },\n {\n name: \"--sales-point <n>\",\n description: \"punto de venta a verificar\",\n },\n {\n name: \"--no-cache\",\n description: \"no reusa ni guarda el ticket WSAA\",\n },\n { name: \"--json\", description: \"salida JSON\" },\n { name: \"--no-color\", description: \"sin colores\" },\n { name: \"-h, --help\", description: \"esta ayuda\" },\n ],\n },\n ],\n examples: [\n \"npx facturas check\",\n \"npx facturas check --sales-point 3\",\n \"npx facturas check --cert arca-test.crt --key arca-test.key\",\n ],\n notes: [\n \"Busca cada valor en este orden: los flags, las variables de entorno y,\",\n \"por último, arca-<entorno>.crt y arca-<entorno>.key en el directorio; de\",\n \"ahí sale también el CUIT y el entorno. Nunca escribe en ARCA: solo lee.\",\n \"Guarda el ticket WSAA en el directorio temporal del sistema para poder\",\n \"repetirse, porque ARCA rechaza un segundo login mientras hay uno\",\n \"vigente; --no-cache no lo lee ni lo escribe.\",\n ],\n },\n issue: {\n summary: CLI_COMMAND_SUMMARIES.issue,\n usage: \"npx facturas issue [opciones]\",\n sections: [\n {\n title: \"Opciones:\",\n rows: [\n { name: \"--sales-point <n>\", description: \"punto de venta a usar\" },\n { name: \"--issuer <condición>\", description: \"condición del emisor\" },\n {\n name: \"--cert <archivo>\",\n description: \"certificado PEM desde un archivo\",\n },\n {\n name: \"--key <archivo>\",\n description: \"clave privada PEM desde un archivo\",\n },\n {\n name: \"--cuit <cuit>\",\n description: \"CUIT, en lugar de ARCA_TAX_ID\",\n },\n {\n name: \"--env <test|production>\",\n description: \"entorno, en lugar de ARCA_ENVIRONMENT\",\n },\n {\n name: \"--dir <directorio>\",\n description: \"dónde buscar los archivos (por defecto: el actual)\",\n },\n {\n name: \"--no-cache\",\n description: \"no reusa ni guarda el ticket WSAA\",\n },\n { name: \"--json\", description: \"salida JSON\" },\n { name: \"--no-color\", description: \"sin colores\" },\n { name: \"-h, --help\", description: \"esta ayuda\" },\n ],\n },\n ],\n examples: [\n \"npx facturas issue --sales-point 3 --issuer monotributo\",\n \"npx facturas issue --sales-point 3 --issuer responsable_inscripto --json\",\n ],\n notes: [\n \"Las condiciones de emisor son monotributo, responsable_inscripto,\",\n \"exento y no_alcanzado. Emite un comprobante real de homologación y se\",\n \"niega fuera de test: corre antes las capas de check, con la misma\",\n \"búsqueda de configuración, y no sigue si alguna falla. En una terminal\",\n \"pregunta el punto de venta y el emisor.\",\n ],\n },\n};\n\n/**\n * Renders one help page. Pure: the same text with and without ANSI, so\n * `--no-color` output is the colored one minus the escapes.\n */\nexport function renderHelp(\n topic: CliHelpTopic,\n options: { color: boolean }\n): string {\n const painter = createPainter(options.color);\n const page = HELP_PAGES[topic];\n const lines = [`facturas ${readCliVersion()}`, \"\"];\n\n if (page.summary !== undefined) {\n lines.push(`${INDENT}${page.summary}`, \"\");\n }\n lines.push(`${INDENT}${page.usage}`, \"\");\n\n for (const section of page.sections) {\n lines.push(painter.dim(section.title), \"\");\n const width = columnWidth(section.rows);\n for (const row of section.rows) {\n const name = section.bold === true ? painter.bold(row.name) : row.name;\n lines.push(\n row.description === undefined\n ? `${INDENT}${name}`\n : `${INDENT}${name}${\" \".repeat(width - row.name.length)}${row.description}`\n );\n }\n lines.push(\"\");\n }\n\n lines.push(painter.dim(\"Ejemplos:\"), \"\");\n for (const example of page.examples) {\n lines.push(`${INDENT}${painter.dim(\"$\")} ${painter.cyan(example)}`);\n }\n\n if (page.notes !== undefined) {\n lines.push(\"\", painter.dim(\"Notas:\"), \"\");\n for (const note of page.notes) {\n lines.push(`${INDENT}${note}`);\n }\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\n/** Where the descriptions start. Rows without one never widen the column. */\nfunction columnWidth(rows: HelpRow[]): number {\n const widest = rows\n .filter((row) => row.description !== undefined)\n .reduce((longest, row) => Math.max(longest, row.name.length), 0);\n return widest + COLUMN_GAP;\n}\n","import {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { isAbsolute, resolve } from \"node:path\";\nimport type { ArcaEnvironment } from \"../internal/types\";\nimport { type ArcaPlanContext, buildArcaPlan } from \"./arca-steps\";\nimport { pasteCertificate, writeManualHint } from \"./cert\";\nimport { createArcaCsrMaterial } from \"./csr\";\nimport { describeTaxIdProblem, normalizeTaxId } from \"./cuit\";\nimport { toEnvironment } from \"./discover\";\nimport { CLI_EXIT, type CliIo, type CliWriter } from \"./output\";\nimport { ask, isInteractive } from \"./prompt\";\n\nconst KEY_FILE_MODE = 0o600;\n/** Three tries at the prompt before the CLI gives up and says why. */\nconst TAX_ID_ATTEMPTS = 3;\nconst MISSING_TAX_ID =\n \"Falta el CUIT. Pasá --cuit 20123456786 o ejecutá init en una terminal.\";\nconst MISSING_ENVIRONMENT =\n \"Falta el entorno. Pasá --env test o --env production.\";\nconst GITIGNORE_PATTERNS = [\"arca-*.key\", \"arca-*.crt\"] as const;\n\nexport type InitFlags = {\n cuit?: string;\n env?: string;\n name?: string;\n dir?: string;\n force?: boolean;\n org?: string;\n /** Leaves the clipboard alone: the CSR gets printed instead. */\n noClipboard?: boolean;\n /** Skips the certificate prompt at the end. */\n noPaste?: boolean;\n};\n\n/** Generates the key and the CSR, then prints the exact ARCA steps. */\nexport async function runInit(\n io: CliIo,\n flags: InitFlags,\n writer: CliWriter\n): Promise<number> {\n const resolved = await resolveInitInput(io, flags);\n if (resolved === undefined) {\n return CLI_EXIT.usage;\n }\n\n const { taxId, environment } = resolved;\n const directory = isAbsolute(flags.dir ?? \"\")\n ? (flags.dir as string)\n : resolve(io.cwd, flags.dir ?? \".\");\n const commonName = flags.name?.trim() || \"facturas\";\n // ARCA's alias fields accept letters and digits only, so the alias is the\n // common name with everything else dropped, plus the environment.\n const alias = `${commonName.replace(/[^A-Za-z0-9]/g, \"\")}${\n environment === \"test\" ? \"Test\" : \"Production\"\n }`;\n const keyName = `arca-${environment}.key`;\n const csrName = `arca-${environment}.csr`;\n const certificateName = `arca-${environment}.crt`;\n const keyPath = resolve(directory, keyName);\n const csrPath = resolve(directory, csrName);\n\n const existing = [keyPath, csrPath].filter((path) => existsSync(path));\n if (existing.length > 0 && flags.force !== true) {\n io.stderr.write(\n `Ya existe ${existing.map((path) => path).join(\" y \")}. Usá --force para sobrescribir.\\n`\n );\n return CLI_EXIT.failed;\n }\n\n const material = createArcaCsrMaterial({\n taxId,\n commonName,\n organization: flags.org?.trim() || taxId,\n });\n mkdirSync(directory, { recursive: true });\n writeFileSync(keyPath, material.privateKeyPem, { mode: KEY_FILE_MODE });\n chmodSync(keyPath, KEY_FILE_MODE);\n writeFileSync(csrPath, material.csrPem);\n\n // Only homologación pastes the CSR into a form: production uploads the file\n // itself, so there is nothing to put in the clipboard.\n const clipboard =\n environment === \"test\" &&\n flags.noClipboard !== true &&\n (await io.copyToClipboard(material.csrPem));\n\n writer.ok(keyName, \"clave privada RSA 2048, permisos 0600\");\n writer.ok(csrName, `CSR para ARCA, CN=${commonName}`);\n if (clipboard) {\n writer.ok(\"portapapeles\", `${csrName} copiado, pegalo en el paso 3`);\n }\n\n const ignored = appendToGitignore(directory);\n if (ignored.length > 0) {\n writer.ok(\".gitignore\", `agregué ${ignored.join(\" y \")}`);\n }\n\n const paste = flags.noPaste !== true && isInteractive(io);\n writePlan(writer, {\n alias,\n certificateName,\n clipboard,\n csrName,\n csrPem: material.csrPem,\n environment,\n paste,\n taxId,\n });\n\n const code = paste\n ? await askForCertificate(io, writer, {\n certificatePath: resolve(directory, certificateName),\n certificateName,\n keyName,\n privateKeyPem: material.privateKeyPem,\n taxId,\n })\n : manualCertificate(writer, certificateName);\n\n writer.blank();\n writer.dim(\"Para tu app las variables son ARCA_TAX_ID, ARCA_ENVIRONMENT,\");\n writer.dim(\"ARCA_CERTIFICATE_PEM y ARCA_PRIVATE_KEY_PEM.\");\n writer.dim(\"Ver https://facturas-sdk.dev/getting-started/quickstart\");\n return code;\n}\n\n/**\n * The certificate, right here, while the browser tab with it is still open.\n * A saved file the CLI never sees is the step where onboarding used to end.\n */\nasync function askForCertificate(\n io: CliIo,\n writer: CliWriter,\n request: {\n certificatePath: string;\n certificateName: string;\n keyName: string;\n privateKeyPem: string;\n taxId: string;\n }\n): Promise<number> {\n const outcome = await pasteCertificate(io, writer, {\n intro: [\n \"Cuando tengas el certificado (paso 4), pegalo acá. Termina solo al ver\",\n \"-----END CERTIFICATE-----. Ctrl-C para hacerlo después con\",\n \"npx facturas cert.\",\n ],\n ...request,\n });\n\n if (outcome === \"saved\") {\n writer.blank();\n writer.line(\"Falta el paso 5 (la autorización a wsfe). Cuando esté:\");\n writer.blank();\n writer.command(\"npx facturas check\");\n return CLI_EXIT.ok;\n }\n if (outcome === \"refused\") {\n return CLI_EXIT.failed;\n }\n writeManualHint(writer, request.certificateName);\n return outcome === \"cancelled\" ? CLI_EXIT.ok : CLI_EXIT.failed;\n}\n\n/** Without a terminal, or with --no-paste, the old hand-off is still true. */\nfunction manualCertificate(writer: CliWriter, certificateName: string): number {\n writeManualHint(writer, certificateName);\n return CLI_EXIT.ok;\n}\n\nasync function resolveInitInput(\n io: CliIo,\n flags: InitFlags\n): Promise<{ taxId: string; environment: ArcaEnvironment } | undefined> {\n const interactive = isInteractive(io);\n const taxId = await resolveTaxId(io, flags, interactive);\n if (\"error\" in taxId) {\n io.stderr.write(`${taxId.error}\\n`);\n return undefined;\n }\n\n const environment = await resolveEnvironment(io, flags, interactive);\n if (environment === undefined) {\n io.stderr.write(`${MISSING_ENVIRONMENT}\\n`);\n return undefined;\n }\n\n return { taxId: taxId.taxId, environment };\n}\n\n/**\n * A CUIT that is absent and one that is wrong are different problems, and the\n * message has to say which. On a terminal a wrong answer is worth another try:\n * the reason goes back to the user and the question is asked again.\n */\nasync function resolveTaxId(\n io: CliIo,\n flags: InitFlags,\n interactive: boolean\n): Promise<{ taxId: string } | { error: string }> {\n const fromFlag = flags.cuit?.trim();\n if (fromFlag !== undefined && fromFlag !== \"\") {\n const problem = describeTaxIdProblem(fromFlag);\n return problem === undefined\n ? { taxId: normalizeTaxId(fromFlag) }\n : { error: problem };\n }\n if (!interactive) {\n return { error: MISSING_TAX_ID };\n }\n\n let problem = MISSING_TAX_ID;\n for (let attempt = 1; attempt <= TAX_ID_ATTEMPTS; attempt += 1) {\n const answer = await ask(io, \"CUIT: \");\n if (answer === \"\") {\n problem = MISSING_TAX_ID;\n } else {\n const invalid = describeTaxIdProblem(answer);\n if (invalid === undefined) {\n return { taxId: normalizeTaxId(answer) };\n }\n problem = invalid;\n }\n if (attempt < TAX_ID_ATTEMPTS) {\n io.stderr.write(`${problem}\\n`);\n }\n }\n return { error: problem };\n}\n\nasync function resolveEnvironment(\n io: CliIo,\n flags: InitFlags,\n interactive: boolean\n): Promise<ArcaEnvironment | undefined> {\n const fromFlag = flags.env?.trim().toLowerCase();\n if (fromFlag !== undefined && fromFlag !== \"\") {\n return toEnvironment(fromFlag);\n }\n if (!interactive) {\n return undefined;\n }\n const answer = await ask(io, \"Entorno [test/production]: \");\n return toEnvironment(answer.trim().toLowerCase());\n}\n\n/** Appends the credential patterns to an existing `.gitignore`. Idempotent. */\nfunction appendToGitignore(directory: string): string[] {\n const path = resolve(directory, \".gitignore\");\n if (!existsSync(path)) {\n return [];\n }\n\n const current = readFileSync(path, \"utf8\");\n const lines = new Set(current.split(\"\\n\").map((line) => line.trim()));\n const missing = GITIGNORE_PATTERNS.filter((pattern) => !lines.has(pattern));\n if (missing.length === 0) {\n return [];\n }\n\n const prefix = current.length > 0 && !current.endsWith(\"\\n\") ? \"\\n\" : \"\";\n writeFileSync(path, `${current}${prefix}${missing.join(\"\\n\")}\\n`);\n return [...missing];\n}\n\nfunction writePlan(\n writer: CliWriter,\n context: ArcaPlanContext & { environment: ArcaEnvironment }\n): void {\n const plan = buildArcaPlan(context.environment, context, writer.painter);\n writer.blank();\n writer.line(plan.heading);\n writer.blank();\n for (const line of plan.lines) {\n writer.line(line.text);\n }\n}\n","import type { IssuedVoucher, IssueOutcome } from \"../services/vouchers-types\";\nimport type { IssueInput } from \"../services/wsfe-derive\";\nimport {\n type CheckFlags,\n type CliCheckReport,\n parseSalesPoint,\n resolveCheckEnvironment,\n runCheckLayers,\n writeCheckReport,\n} from \"./check\";\nimport { describeUnknownError } from \"./diagnose\";\nimport { CLI_EXIT, type CliIo, type CliWriter } from \"./output\";\nimport { ask, isInteractive } from \"./prompt\";\n\n/** One peso, in minor units. The smoke test never issues more than this. */\nconst SMOKE_TEST_MINOR_UNITS = 100;\nconst SMOKE_TEST_VAT_RATE = 21;\nconst SALES_POINT_DIGITS = 5;\nconst VOUCHER_NUMBER_DIGITS = 8;\n\nconst ISSUER_CONDITIONS = [\n \"monotributo\",\n \"responsable_inscripto\",\n \"exento\",\n \"no_alcanzado\",\n] as const;\n\ntype IssuerCondition = (typeof ISSUER_CONDITIONS)[number];\n\n/**\n * The smoke test always builds an items input, never the reviewed-amounts one,\n * so `items` is present and the printed call can read it without a guard.\n */\ntype SmokeTestItem = { gross: number; vat: number } | { amount: number };\ntype SmokeTestInput = IssueInput & { items: readonly SmokeTestItem[] };\n\nexport type IssueFlags = CheckFlags & {\n issuer?: string;\n};\n\n/** Issues exactly one ARS 1 invoice in homologación. Refuses anywhere else. */\nexport async function runIssue(\n io: CliIo,\n flags: IssueFlags,\n writer: CliWriter,\n json: boolean\n): Promise<number> {\n // Refuse before anything else when the environment is already known to be\n // the wrong one. When nothing says which it is, the check layers run and\n // name the real problem, and the guard below runs again on what they found.\n const environment = resolveCheckEnvironment(io, flags);\n if (environment !== undefined && environment !== \"test\") {\n return refuse(io);\n }\n\n const parameters = await resolveIssueInput(\n json ? { ...io, stdout: io.stderr } : io,\n flags\n );\n if (parameters === undefined) {\n return CLI_EXIT.usage;\n }\n\n const { report, client } = await runCheckLayers(io, flags);\n if (!(report.ok && client)) {\n if (json) {\n writer.json(report);\n } else {\n writeCheckReport(writer, report);\n }\n return CLI_EXIT.failed;\n }\n if (report.environment !== \"test\") {\n return refuse(io);\n }\n\n const input = buildSmokeTestInput(parameters.issuer, parameters.salesPoint);\n // The layers passed, so ARCA answered a moment ago; it can still fail on the\n // next number or the authorization. That is a diagnosis like any other, not\n // a stack trace, and with --json it still has to be one JSON object.\n let outcome: IssueOutcome;\n try {\n outcome = await client.issue(input);\n } catch (error) {\n return writeIssueError(writer, report, error, json);\n }\n if (json) {\n writer.json(outcome);\n return outcome.kind === \"authorized\" ? CLI_EXIT.ok : CLI_EXIT.failed;\n }\n return writeOutcome(writer, outcome, input);\n}\n\n/** The same safe message and code the check layers print, in both shapes. */\nfunction writeIssueError(\n writer: CliWriter,\n report: CliCheckReport,\n error: unknown,\n json: boolean\n): number {\n const unknown = describeUnknownError(error);\n if (json) {\n writer.json({\n ok: false,\n ...(report.environment === undefined\n ? {}\n : { environment: report.environment }),\n ...(report.taxId === undefined ? {} : { taxId: report.taxId }),\n error: {\n ...(unknown.code === undefined ? {} : { code: unknown.code }),\n message: unknown.diagnosis,\n },\n });\n return CLI_EXIT.failed;\n }\n writer.fail(\"emisión\");\n writer.note(unknown.diagnosis);\n writer.note(\n \"No sabemos si ARCA llegó a autorizar; consultá el punto de venta antes de repetir.\"\n );\n return CLI_EXIT.failed;\n}\n\nfunction refuse(io: CliIo): number {\n io.stderr.write(\n \"issue solo emite en homologación. Cambiá ARCA_ENVIRONMENT=test.\\n\"\n );\n return CLI_EXIT.failed;\n}\n\nasync function resolveIssueInput(\n io: CliIo,\n flags: IssueFlags\n): Promise<{ issuer: IssuerCondition; salesPoint: number } | undefined> {\n const interactive = isInteractive(io);\n const salesPoint = await resolveSalesPoint(io, flags, interactive);\n if (salesPoint === undefined) {\n io.stderr.write(\"Falta el punto de venta. Pasá --sales-point 3.\\n\");\n return undefined;\n }\n\n const issuer = await resolveIssuer(io, flags, interactive);\n if (issuer === undefined) {\n io.stderr.write(\n `Falta la condición del emisor. Pasá --issuer ${ISSUER_CONDITIONS.join(\"|\")}.\\n`\n );\n return undefined;\n }\n\n return { issuer, salesPoint };\n}\n\nasync function resolveSalesPoint(\n io: CliIo,\n flags: IssueFlags,\n interactive: boolean\n): Promise<number | undefined> {\n if (flags.salesPoint !== undefined) {\n return flags.salesPoint;\n }\n if (!interactive) {\n return undefined;\n }\n // The same reading as `--sales-point`: a typo is a typo at the prompt too.\n return parseSalesPoint((await ask(io, \"Punto de venta: \")).trim());\n}\n\nasync function resolveIssuer(\n io: CliIo,\n flags: IssueFlags,\n interactive: boolean\n): Promise<IssuerCondition | undefined> {\n const fromFlag = flags.issuer?.trim();\n if (fromFlag) {\n return toIssuerCondition(fromFlag);\n }\n if (!interactive) {\n return undefined;\n }\n const answer = await ask(io, `Emisor [${ISSUER_CONDITIONS.join(\"/\")}]: `);\n return toIssuerCondition(answer.trim());\n}\n\nfunction toIssuerCondition(value: string): IssuerCondition | undefined {\n return ISSUER_CONDITIONS.includes(value as IssuerCondition)\n ? (value as IssuerCondition)\n : undefined;\n}\n\n/** ARS 1: a VAT item for class B, a plain amount for class C. */\nexport function buildSmokeTestInput(\n issuer: IssuerCondition,\n salesPoint: number\n): SmokeTestInput {\n if (issuer === \"responsable_inscripto\") {\n return {\n issuer,\n salesPoint,\n to: { condition: \"consumidor_final\" },\n items: [{ gross: SMOKE_TEST_MINOR_UNITS, vat: SMOKE_TEST_VAT_RATE }],\n };\n }\n return {\n issuer,\n salesPoint,\n to: { condition: \"consumidor_final\" },\n items: [{ amount: SMOKE_TEST_MINOR_UNITS }],\n };\n}\n\nfunction writeOutcome(\n writer: CliWriter,\n outcome: IssueOutcome,\n input: SmokeTestInput\n): number {\n if (outcome.kind === \"authorized\") {\n writer.ok(describeVoucher(outcome.voucher));\n writeIssueCall(writer, input);\n return CLI_EXIT.ok;\n }\n\n if (outcome.kind === \"rejected\") {\n writer.fail(\n `Factura rechazada - ${describeCoordinates(outcome.attempted)}`\n );\n for (const issue of outcome.issues) {\n writer.note(\n issue.code === undefined\n ? issue.message\n : `${issue.code} ${issue.message}`\n );\n }\n return CLI_EXIT.failed;\n }\n\n if (outcome.kind === \"conflict\") {\n writer.fail(`conflicto en ${describeCoordinates(outcome.attempted)}`);\n writer.note(outcome.reason);\n writer.note(\n \"Hay otro comprobante en ese número; detené el flujo e investigá.\"\n );\n return CLI_EXIT.failed;\n }\n\n writer.fail(`indeterminado ${describeCoordinates(outcome.attempted)}`);\n writer.note(`${outcome.attempt.reason}, consulta ${outcome.lookup.kind}`);\n writer.note(\n \"Conservá el número y la evidencia; conciliá o repetí el mismo input con su clave.\"\n );\n return CLI_EXIT.failed;\n}\n\nfunction describeVoucher(voucher: IssuedVoucher): string {\n return [\n `Factura ${voucher.voucherClass} emitida - ${describeCoordinates(voucher)}`,\n `CAE ${voucher.cae}`,\n `Vto. CAE ${formatArcaDate(voucher.caeExpiry)}`,\n `ARS ${formatMinorUnits(voucher.amounts.sentTotal)}`,\n ].join(\" \");\n}\n\nfunction describeCoordinates(coordinates: {\n salesPoint: number;\n number: number;\n}): string {\n return `${String(coordinates.salesPoint).padStart(SALES_POINT_DIGITS, \"0\")}-${String(\n coordinates.number\n ).padStart(VOUCHER_NUMBER_DIGITS, \"0\")}`;\n}\n\n/** `20260916` as ARCA sends it becomes `2026-09-16`. */\nfunction formatArcaDate(value: string): string {\n return /^\\d{8}$/.test(value)\n ? `${value.slice(0, 4)}-${value.slice(4, 6)}-${value.slice(6, 8)}`\n : value;\n}\n\n/** Minor units to the castellano form: thousands with `.`, decimals with `,`. */\nexport function formatMinorUnits(minorUnits: number): string {\n const negative = minorUnits < 0;\n const digits = String(Math.abs(minorUnits)).padStart(3, \"0\");\n const whole = digits.slice(0, -2);\n const cents = digits.slice(-2);\n const grouped = whole.replace(/\\B(?=(\\d{3})+(?!\\d))/g, \".\");\n return `${negative ? \"-\" : \"\"}${grouped},${cents}`;\n}\n\n/** Prints the exact call, so the smoke test doubles as the first snippet. */\nfunction writeIssueCall(writer: CliWriter, input: SmokeTestInput): void {\n writer.blank();\n writer.line(\"Esta es la llamada que hizo el CLI. Pegala en tu aplicación:\");\n writer.blank();\n writer.line(\" const factura = await arca.issue({\");\n writer.line(` issuer: \"${input.issuer}\",`);\n writer.line(` salesPoint: ${input.salesPoint},`);\n writer.line(' to: { condition: \"consumidor_final\" },');\n writer.line(` items: [${input.items.map(formatItem).join(\", \")}],`);\n writer.line(\" });\");\n}\n\nfunction formatItem(item: SmokeTestItem): string {\n const fields = Object.entries(item)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => `${key}: ${String(value)}`);\n return `{ ${fields.join(\", \")} }`;\n}\n"],"mappings":"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","names":["join","existsSync","readFileSync","resolve","text","resolve","existsSync","readFileSync","readFileSync","isAbsolute","resolve","text","text","toEnvironment","isAbsolute","resolve","readFileSync","text","readFileSync","INDENT","COLUMN_GAP","columnWidth","existsSync","readFileSync","writeFileSync","isAbsolute","resolve","isAbsolute","resolve","existsSync","writeFileSync","resolveTaxId","problem","readFileSync","refuse","join","text"]}
|