@deuriib/better-dgii-ecf 0.0.0-stage → 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Deuri Vasquez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.es.md ADDED
@@ -0,0 +1,159 @@
1
+ # better-dgii-ecf
2
+
3
+ [English](README.md) · [Español](README.es.md)
4
+
5
+ > Plugin de [Better Auth](https://better-auth.com) para los servicios de facturación
6
+ > electrónica (**e-CF**) de la **DGII** de República Dominicana, construido sobre
7
+ > [`@deuriib/dgii-ecf`](https://www.npmjs.com/package/@deuriib/dgii-ecf).
8
+
9
+ [![npm](https://img.shields.io/npm/v/@deuriib/better-dgii-ecf.svg?label=npm)](https://www.npmjs.com/package/@deuriib/better-dgii-ecf)
10
+ [![CI](https://github.com/deuriib/better-dgii-ecf/actions/workflows/ci.yml/badge.svg)](https://github.com/deuriib/better-dgii-ecf/actions/workflows/ci.yml)
11
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
12
+
13
+ `better-dgii-ecf` convierte el SDK de la DGII en una API autenticada. Decide **qué
14
+ contribuyente** actúa en cada petición, resuelve su certificado **en el servidor** y
15
+ registra cada transmisión para que un reintento no pueda emitir dos veces el mismo
16
+ comprobante fiscal.
17
+
18
+ Es un plugin, no un generador de documentos: tu aplicación modela la factura, el plugin
19
+ se encarga de la identidad, las credenciales, la idempotencia y la auditoría.
20
+
21
+ ## ✨ Por qué existe
22
+
23
+ Una integración con la DGII tiene tres problemas que el framework de autenticación no
24
+ resuelve:
25
+
26
+ | Problema | Qué pasa sin el plugin | Qué hace el plugin |
27
+ | ------------------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
28
+ | **¿Quién factura?** | El RNC viene del navegador, así que cualquiera factura como cualquier contribuyente. | Resuelve el contribuyente desde la organización, la petición o un mapeo del servidor, y luego lo autoriza. |
29
+ | **¿Dónde vive el certificado?** | El `.p12` termina en el cliente o en cada cuerpo de petición. | Resuelve la llave por un callback exclusivo del servidor, firma en el servidor y nunca devuelve el token de la DGII. |
30
+ | **¿Llegó el comprobante?** | Un timeout más un reintento emite dos veces el mismo e-NCF. | Escribe una fila `pending` antes de transmitir y reproduce el envío conocido en vez de repetirlo. |
31
+
32
+ ## 📦 Instalación
33
+
34
+ ```bash
35
+ bun add @deuriib/better-dgii-ecf @deuriib/dgii-ecf better-auth
36
+ # o: npm install @deuriib/better-dgii-ecf @deuriib/dgii-ecf better-auth
37
+ ```
38
+
39
+ Dependencias peer: `better-auth@^1.7`, `@deuriib/dgii-ecf@^0.6`.
40
+
41
+ ## 🚀 Inicio rápido — modo organización
42
+
43
+ El modo recomendado. El `taxPayerId` vive en la organización, así que el RNC con el que
44
+ un usuario puede facturar es el de la organización a la que pertenece.
45
+
46
+ ```ts
47
+ // auth.ts
48
+ import { betterAuth } from 'better-auth';
49
+ import { organization } from 'better-auth/plugins';
50
+ import { P12Reader, Environment } from '@deuriib/dgii-ecf';
51
+ import { dgiiEcf, dgiiEcfOrganizationSchema } from '@deuriib/better-dgii-ecf';
52
+
53
+ export const auth = betterAuth({
54
+ plugins: [
55
+ organization({
56
+ // Hace escribible el campo `taxPayerId` de la organización.
57
+ schema: { organization: dgiiEcfOrganizationSchema() },
58
+ }),
59
+ dgiiEcf({
60
+ environment: Environment.Cert,
61
+ // El único lugar donde se lee un certificado. Se ejecuta en el servidor,
62
+ // por contribuyente, nunca desde el cuerpo de una petición.
63
+ credentials: async ({ taxPayerId }) => {
64
+ const p12 = await certificates.for(taxPayerId); // tu almacenamiento
65
+ return new P12Reader(p12.password)
66
+ .getKeyFromStringBase64(p12.base64)
67
+ .unwrapOrThrow();
68
+ },
69
+ status: { apiKey: process.env.DGII_STATUS_API_KEY! },
70
+ }),
71
+ ],
72
+ });
73
+ ```
74
+
75
+ ```ts
76
+ // auth-client.ts
77
+ import { createAuthClient } from 'better-auth/client';
78
+ import { organizationClient } from 'better-auth/client/plugins';
79
+ import { dgiiEcfClient } from '@deuriib/better-dgii-ecf/client';
80
+
81
+ export const authClient = createAuthClient({
82
+ plugins: [organizationClient(), dgiiEcfClient()],
83
+ });
84
+ ```
85
+
86
+ ```ts
87
+ const { data, error } = await authClient.dgiiEcf.documents({
88
+ xml: invoiceXml, // construido por tu aplicación
89
+ sign: true, // firmado aquí, con la llave de la organización
90
+ });
91
+ ```
92
+
93
+ ## 🚀 Inicio rápido — modo por petición
94
+
95
+ Sin el plugin de organización: cada llamada indica su contribuyente. Es la forma de un
96
+ despliegue de un solo emisor, y funciona porque no hay un modelo de inquilino contra el
97
+ cual comparar el identificador.
98
+
99
+ ```ts
100
+ dgiiEcf({
101
+ environment: Environment.Dev,
102
+ credentials: async () => loadSingleTenantCertificate(),
103
+ });
104
+ ```
105
+
106
+ ```ts
107
+ await auth.api.dgiiEcfSendDocument({
108
+ body: { xml, sign: true, taxPayerId: '131123456' },
109
+ headers,
110
+ });
111
+ ```
112
+
113
+ Ambos modos son de primera clase; el
114
+ [orden de resolución](docs/usage.md#which-taxpayer-does-a-call-act-for) es fijo y
115
+ `GET /dgii-ecf/taxpayer` lo reporta, para que la interfaz nunca tenga que adivinar.
116
+
117
+ ## 🔐 Postura de seguridad
118
+
119
+ - **Ningún certificado en el navegador.** La llave se resuelve por un callback del
120
+ servidor; `sign: true` firma dentro del proceso que la tiene.
121
+ - **Ningún token de la DGII en la red.** `authenticate` devuelve `issuedAt` /
122
+ `expiresAt`; el token no sale del servidor, ni siquiera en un cuerpo de error.
123
+ - **El emisor debe coincidir.** Un documento cuyo `RNCEmisor` difiere del contribuyente
124
+ autorizado se rechaza.
125
+ - **Idempotente por construcción.** La llave de repetición es el SHA-256 del documento,
126
+ y la fila `pending` se escribe antes de transmitir.
127
+ - **Nada fiscal en la tabla de auditoría.** Solo un hash, el e-NCF, el track id y la
128
+ operación.
129
+
130
+ Lee [docs/security.md](docs/security.md) para el modelo de amenazas, incluido lo que el
131
+ plugin **no** protege a propósito.
132
+
133
+ ## 🧪 Desarrollo
134
+
135
+ Todo corre por [mise](https://mise.jdx.dev) — local y en CI, con la misma cadena de
136
+ herramientas fijada.
137
+
138
+ ```bash
139
+ mise install # Node, Bun, pre-commit y gitleaks
140
+ mise run bootstrap # dependencias + git hooks
141
+ mise run ci # formato + tipos + cobertura + build + chequeos del paquete
142
+ mise tasks # lista todas las tareas
143
+ ```
144
+
145
+ ## 📚 Documentación
146
+
147
+ - [Guía de uso](docs/usage.md) — modos, endpoints, repetición, errores
148
+ - [Arquitectura](docs/architecture.md) — ciclo de vida y modelo de datos
149
+ - [Seguridad](docs/security.md) — modelo de amenazas y garantías
150
+ - [Decisiones](docs/decisions.md) — por qué los valores por defecto son estos
151
+ - [Contribuir](CONTRIBUTING.md) · [Código de Conducta](CODE_OF_CONDUCT.md)
152
+
153
+ ## ⚖️ Licencia
154
+
155
+ [MIT](LICENSE) © 2026 Deuri Vasquez.
156
+
157
+ > No está afiliado a la DGII. Es una implementación independiente de la especificación
158
+ > técnica pública del e-CF (Ley 32-23, Decreto 587-24). Valida siempre contra la
159
+ > [documentación oficial](https://dgii.gov.do/cicloContribuyente/facturacion/comprobantesFiscalesElectronicosE-CF/Paginas/default.aspx).
package/README.md CHANGED
@@ -1,3 +1,197 @@
1
- # Temporary Holding Version
1
+ # better-dgii-ecf
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [English](README.md) · [Español](README.es.md)
4
+
5
+ > A [Better Auth](https://better-auth.com) plugin for the Dominican Republic's **DGII**
6
+ > electronic invoicing (e-CF) services, built on
7
+ > [`@deuriib/dgii-ecf`](https://www.npmjs.com/package/@deuriib/dgii-ecf).
8
+
9
+ [![npm](https://img.shields.io/npm/v/@deuriib/better-dgii-ecf.svg?label=npm)](https://www.npmjs.com/package/@deuriib/better-dgii-ecf)
10
+ [![CI](https://github.com/deuriib/better-dgii-ecf/actions/workflows/ci.yml/badge.svg)](https://github.com/deuriib/better-dgii-ecf/actions/workflows/ci.yml)
11
+ [![CodeQL](https://github.com/deuriib/better-dgii-ecf/actions/workflows/codeql.yml/badge.svg)](https://github.com/deuriib/better-dgii-ecf/actions/workflows/codeql.yml)
12
+ [![npm provenance](https://img.shields.io/badge/provenance-OIDC-blue)](https://docs.npmjs.com/trusted-publishers)
13
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
14
+ [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://www.conventionalcommits.org/)
15
+
16
+ `better-dgii-ecf` turns the DGII SDK into an authenticated API surface. It decides
17
+ **which taxpayer** a request acts for, resolves that taxpayer's certificate
18
+ **server-side**, and records every transmission so a retry can never issue the same
19
+ fiscal document twice.
20
+
21
+ It is a plugin, not a document builder: your application owns the invoice model, the
22
+ plugin owns identity, credentials, replay safety and the audit trail.
23
+
24
+ ## ✨ Why this plugin exists
25
+
26
+ A DGII integration has three problems that authentication frameworks do not solve:
27
+
28
+ | Problem | What goes wrong without it | What the plugin does |
29
+ | ------------------------------------ | ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
30
+ | **Who is invoicing?** | The RNC comes from the browser, so any user can invoice as any taxpayer. | Resolves the taxpayer from the organization, the request, or a server-side mapping — then authorizes it. |
31
+ | **Where does the certificate live?** | The `.p12` ends up in the client, or in every request body. | Resolves key material through a server-only callback; signs server-side; never returns a DGII token. |
32
+ | **Did the invoice land?** | A timeout plus a retry issues the same e-NCF twice. | Persists a pending row before transmitting and replays a known submission instead of re-sending it. |
33
+
34
+ ## 📦 Install
35
+
36
+ ```bash
37
+ bun add @deuriib/better-dgii-ecf @deuriib/dgii-ecf better-auth
38
+ # or: npm install @deuriib/better-dgii-ecf @deuriib/dgii-ecf better-auth
39
+ ```
40
+
41
+ Peer dependencies: `better-auth@^1.7`, `@deuriib/dgii-ecf@^0.6`.
42
+
43
+ ## 🚀 Quick start — organization mode
44
+
45
+ The recommended setup. `taxPayerId` lives on the organization, so the RNC a user can
46
+ invoice under is the organization they belong to.
47
+
48
+ ```ts
49
+ // auth.ts
50
+ import { betterAuth } from 'better-auth';
51
+ import { organization } from 'better-auth/plugins';
52
+ import { P12Reader, Environment } from '@deuriib/dgii-ecf';
53
+ import { dgiiEcf, dgiiEcfOrganizationSchema } from '@deuriib/better-dgii-ecf';
54
+
55
+ export const auth = betterAuth({
56
+ plugins: [
57
+ organization({
58
+ // Makes `taxPayerId` writable on the organization (create + update).
59
+ schema: { organization: dgiiEcfOrganizationSchema() },
60
+ }),
61
+ dgiiEcf({
62
+ environment: Environment.Cert,
63
+ // The only place a certificate is ever read. Called server-side, once per
64
+ // taxpayer, never from a request body.
65
+ credentials: async ({ taxPayerId }) => {
66
+ const p12 = await certificates.for(taxPayerId); // your storage
67
+ return new P12Reader(p12.password)
68
+ .getKeyFromStringBase64(p12.base64)
69
+ .unwrapOrThrow();
70
+ },
71
+ status: { apiKey: process.env.DGII_STATUS_API_KEY! },
72
+ }),
73
+ ],
74
+ });
75
+ ```
76
+
77
+ ```ts
78
+ // auth-client.ts
79
+ import { createAuthClient } from 'better-auth/client';
80
+ import { organizationClient } from 'better-auth/client/plugins';
81
+ import { dgiiEcfClient } from '@deuriib/better-dgii-ecf/client';
82
+
83
+ export const authClient = createAuthClient({
84
+ plugins: [organizationClient(), dgiiEcfClient()],
85
+ });
86
+ ```
87
+
88
+ ```ts
89
+ const { data, error } = await authClient.dgiiEcf.documents({
90
+ xml: invoiceXml, // built by your application
91
+ sign: true, // signed here, with the organization's key
92
+ });
93
+ ```
94
+
95
+ ## 🚀 Quick start — per-call mode
96
+
97
+ No organization plugin: every call names its taxpayer. This is the single-tenant shape,
98
+ and it works because there is no tenant model to check the id against.
99
+
100
+ ```ts
101
+ dgiiEcf({
102
+ environment: Environment.Dev,
103
+ credentials: async () => loadSingleTenantCertificate(),
104
+ });
105
+ ```
106
+
107
+ ```ts
108
+ await auth.api.dgiiEcfSendDocument({
109
+ body: { xml, sign: true, taxPayerId: '131123456' },
110
+ headers,
111
+ });
112
+ ```
113
+
114
+ Both modes are first class;
115
+ [the resolution order](docs/usage.md#which-taxpayer-does-a-call-act-for) is fixed and
116
+ reported back by `GET /dgii-ecf/taxpayer`, so a UI never has to guess.
117
+
118
+ ## 🔌 What you get
119
+
120
+ | Method | Path | Purpose |
121
+ | -------------------------------------- | ---------------------------------------------- | ----------------------------------------------------------------- |
122
+ | `dgiiEcf.taxpayer` | `GET /dgii-ecf/taxpayer` | Resolve which taxpayer the next call uses, and why |
123
+ | `dgiiEcf.authenticate` | `POST /dgii-ecf/authenticate` | Warm the DGII token; returns the validity window, never the token |
124
+ | `dgiiEcf.documents` | `POST /dgii-ecf/documents` | Submit an e-CF, routing on the document's own content |
125
+ | `dgiiEcf.documents.electronic` | `POST /dgii-ecf/documents/electronic` | Submit to the general e-CF reception only |
126
+ | `dgiiEcf.documents.summary` | `POST /dgii-ecf/documents/summary` | Submit an RFCE summary invoice |
127
+ | `dgiiEcf.documents.commercialApproval` | `POST /dgii-ecf/documents/commercial-approval` | Submit an ACECF |
128
+ | `dgiiEcf.documents.voidRange` | `POST /dgii-ecf/documents/void-range` | Void an e-NCF range (ANECF) |
129
+ | `dgiiEcf.documents.reconcile` | `POST /dgii-ecf/documents/reconcile` | Resolve a submission whose outcome is unknown |
130
+ | `dgiiEcf.tracks` | `GET /dgii-ecf/tracks` | Read a track result |
131
+ | `dgiiEcf.inquiries.status` | `POST /dgii-ecf/inquiries/status` | Existence check by e-NCF |
132
+ | `dgiiEcf.inquiries.tracks` | `POST /dgii-ecf/inquiries/tracks` | Every track DGII holds for an e-NCF |
133
+ | `dgiiEcf.inquiries.summary` | `POST /dgii-ecf/inquiries/summary` | RFCE inquiry (production only) |
134
+ | `dgiiEcf.directories.customers` | `GET /dgii-ecf/directories/customers` | Receiver service directory |
135
+ | `dgiiEcf.directories.all` | `GET /dgii-ecf/directories/all` | Every receiver that publishes URLs |
136
+ | `dgiiEcf.serviceStatus` | `GET /dgii-ecf/service-status` | DGII service status |
137
+ | `dgiiEcf.maintenanceWindows` | `GET /dgii-ecf/maintenance-windows` | DGII maintenance windows |
138
+ | `dgiiEcf.serviceAvailability` | `GET /dgii-ecf/service-availability` | Is one environment inside a window |
139
+ | `dgiiEcf.submissions` | `GET /dgii-ecf/submissions` | The submission audit trail |
140
+
141
+ Every response echoes `taxPayerId`, `organizationId` and `environment`, so a caller can
142
+ always tell which identity acted.
143
+
144
+ ## 🔐 Security posture
145
+
146
+ - **No certificate in a browser.** Key material is resolved through a server-only
147
+ callback; `sign: true` signs inside the process that holds it.
148
+ - **No DGII token on the wire.** `authenticate` returns `issuedAt` / `expiresAt`; the
149
+ bearer token never leaves the server, not even in an error body.
150
+ - **The issuer must match.** A document whose `RNCEmisor` differs from the authorized
151
+ taxpayer is refused, so a member of organization A cannot submit a document for RNC B.
152
+ - **Replay safe by construction.** The replay key defaults to the SHA-256 of the
153
+ document, and the pending row is written before transmission.
154
+ - **No fiscal content in the audit table.** Only a hash, the e-NCF, the track id and the
155
+ operation.
156
+
157
+ Read [docs/security.md](docs/security.md) for the threat model, including what the
158
+ plugin deliberately does **not** protect against.
159
+
160
+ ## 🧪 Development
161
+
162
+ Everything runs through [mise](https://mise.jdx.dev) — locally and in CI, with the same
163
+ pinned toolchain.
164
+
165
+ ```bash
166
+ mise install # provision Node, Bun, pre-commit, gitleaks
167
+ mise run bootstrap # dependencies + git hooks
168
+ mise run ci # format check + typecheck + coverage + build + pack checks
169
+ mise tasks # list every task
170
+ ```
171
+
172
+ | Task | What it does |
173
+ | --------------------- | ------------------------------------------------------- |
174
+ | `mise run lint` | Prettier check + `tsc --noEmit` |
175
+ | `mise run test` | Vitest |
176
+ | `mise run coverage` | Vitest with thresholds enforced |
177
+ | `mise run build` | ESM + CJS + declarations |
178
+ | `mise run pack-check` | `publint` + `are-the-types-wrong` on the packed tarball |
179
+ | `mise run publish` | OIDC trusted publish (no token on disk) |
180
+
181
+ ## 📚 Documentation
182
+
183
+ - [Usage guide](docs/usage.md) — modes, endpoints, replay, errors
184
+ - [Architecture](docs/architecture.md) — request lifecycle and data model
185
+ - [Security](docs/security.md) — threat model and guarantees
186
+ - [Decision record](docs/decisions.md) — why the defaults are what they are
187
+ - [Releasing](docs/releasing.md) — trusted publishing, provenance, hotfixes
188
+ - [Contributing](CONTRIBUTING.md) · [Code of Conduct](CODE_OF_CONDUCT.md)
189
+
190
+ ## ⚖️ License
191
+
192
+ [MIT](LICENSE) © 2026 Deuri Vasquez.
193
+
194
+ > Not affiliated with the DGII. This is an independent implementation of the publicly
195
+ > documented e-CF specification (Ley 32-23, Decreto 587-24). Always validate against the
196
+ > official
197
+ > [DGII documentation](https://dgii.gov.do/cicloContribuyente/facturacion/comprobantesFiscalesElectronicosE-CF/Paginas/default.aspx).
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ // src/client.ts
4
+ var dgiiEcfClient = () => ({
5
+ id: "dgii-ecf",
6
+ $InferServerPlugin: {}
7
+ });
8
+
9
+ exports.dgiiEcfClient = dgiiEcfClient;
10
+ //# sourceMappingURL=client.cjs.map
11
+ //# sourceMappingURL=client.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";;;AAqBO,IAAM,gBAAgB,OAC1B;AAAA,EACC,EAAA,EAAI,UAAA;AAAA,EACJ,oBAAoB;AACtB,CAAA","file":"client.cjs","sourcesContent":["import type { BetterAuthClientPlugin } from 'better-auth/client';\nimport type { DgiiEcfPlugin } from './plugin.js';\n\n/**\n * Client plugin for {@link import('./plugin.js').dgiiEcf}.\n *\n * It adds no runtime code: Better Auth infers every method from the server\n * plugin's endpoints, so the client cannot drift from the server — a renamed\n * path breaks the build instead of the invoice. Methods are namespaced under\n * `dgiiEcf`:\n *\n * ```ts\n * await authClient.dgiiEcf.documents({ xml, sign: true });\n * await authClient.dgiiEcf.inquiries.status({ ncf, taxPayerId });\n * await authClient.dgiiEcf.serviceStatus();\n * ```\n *\n * The `id` must match the server plugin's `id` so Better Auth can pair them.\n * Importing this module pulls only types, which is what makes it safe to use\n * from a browser bundle.\n */\nexport const dgiiEcfClient = () =>\n ({\n id: 'dgii-ecf',\n $InferServerPlugin: {} as DgiiEcfPlugin,\n }) satisfies BetterAuthClientPlugin;\n\nexport type DgiiEcfClientPlugin = ReturnType<typeof dgiiEcfClient>;\n"]}
@@ -0,0 +1,31 @@
1
+ import { D as DgiiEcfPlugin } from './plugin-BVYTmUJU.cjs';
2
+ import '@deuriib/dgii-ecf';
3
+ import 'better-auth';
4
+ import 'zod/v4/core';
5
+ import '@better-auth/core/db';
6
+
7
+ /**
8
+ * Client plugin for {@link import('./plugin.js').dgiiEcf}.
9
+ *
10
+ * It adds no runtime code: Better Auth infers every method from the server
11
+ * plugin's endpoints, so the client cannot drift from the server — a renamed
12
+ * path breaks the build instead of the invoice. Methods are namespaced under
13
+ * `dgiiEcf`:
14
+ *
15
+ * ```ts
16
+ * await authClient.dgiiEcf.documents({ xml, sign: true });
17
+ * await authClient.dgiiEcf.inquiries.status({ ncf, taxPayerId });
18
+ * await authClient.dgiiEcf.serviceStatus();
19
+ * ```
20
+ *
21
+ * The `id` must match the server plugin's `id` so Better Auth can pair them.
22
+ * Importing this module pulls only types, which is what makes it safe to use
23
+ * from a browser bundle.
24
+ */
25
+ declare const dgiiEcfClient: () => {
26
+ id: "dgii-ecf";
27
+ $InferServerPlugin: DgiiEcfPlugin;
28
+ };
29
+ type DgiiEcfClientPlugin = ReturnType<typeof dgiiEcfClient>;
30
+
31
+ export { type DgiiEcfClientPlugin, dgiiEcfClient };
@@ -0,0 +1,31 @@
1
+ import { D as DgiiEcfPlugin } from './plugin-BVYTmUJU.js';
2
+ import '@deuriib/dgii-ecf';
3
+ import 'better-auth';
4
+ import 'zod/v4/core';
5
+ import '@better-auth/core/db';
6
+
7
+ /**
8
+ * Client plugin for {@link import('./plugin.js').dgiiEcf}.
9
+ *
10
+ * It adds no runtime code: Better Auth infers every method from the server
11
+ * plugin's endpoints, so the client cannot drift from the server — a renamed
12
+ * path breaks the build instead of the invoice. Methods are namespaced under
13
+ * `dgiiEcf`:
14
+ *
15
+ * ```ts
16
+ * await authClient.dgiiEcf.documents({ xml, sign: true });
17
+ * await authClient.dgiiEcf.inquiries.status({ ncf, taxPayerId });
18
+ * await authClient.dgiiEcf.serviceStatus();
19
+ * ```
20
+ *
21
+ * The `id` must match the server plugin's `id` so Better Auth can pair them.
22
+ * Importing this module pulls only types, which is what makes it safe to use
23
+ * from a browser bundle.
24
+ */
25
+ declare const dgiiEcfClient: () => {
26
+ id: "dgii-ecf";
27
+ $InferServerPlugin: DgiiEcfPlugin;
28
+ };
29
+ type DgiiEcfClientPlugin = ReturnType<typeof dgiiEcfClient>;
30
+
31
+ export { type DgiiEcfClientPlugin, dgiiEcfClient };
package/dist/client.js ADDED
@@ -0,0 +1,9 @@
1
+ // src/client.ts
2
+ var dgiiEcfClient = () => ({
3
+ id: "dgii-ecf",
4
+ $InferServerPlugin: {}
5
+ });
6
+
7
+ export { dgiiEcfClient };
8
+ //# sourceMappingURL=client.js.map
9
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";AAqBO,IAAM,gBAAgB,OAC1B;AAAA,EACC,EAAA,EAAI,UAAA;AAAA,EACJ,oBAAoB;AACtB,CAAA","file":"client.js","sourcesContent":["import type { BetterAuthClientPlugin } from 'better-auth/client';\nimport type { DgiiEcfPlugin } from './plugin.js';\n\n/**\n * Client plugin for {@link import('./plugin.js').dgiiEcf}.\n *\n * It adds no runtime code: Better Auth infers every method from the server\n * plugin's endpoints, so the client cannot drift from the server — a renamed\n * path breaks the build instead of the invoice. Methods are namespaced under\n * `dgiiEcf`:\n *\n * ```ts\n * await authClient.dgiiEcf.documents({ xml, sign: true });\n * await authClient.dgiiEcf.inquiries.status({ ncf, taxPayerId });\n * await authClient.dgiiEcf.serviceStatus();\n * ```\n *\n * The `id` must match the server plugin's `id` so Better Auth can pair them.\n * Importing this module pulls only types, which is what makes it safe to use\n * from a browser bundle.\n */\nexport const dgiiEcfClient = () =>\n ({\n id: 'dgii-ecf',\n $InferServerPlugin: {} as DgiiEcfPlugin,\n }) satisfies BetterAuthClientPlugin;\n\nexport type DgiiEcfClientPlugin = ReturnType<typeof dgiiEcfClient>;\n"]}