sgp-sdk 1.2.0 → 2.0.0-beta.2

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.
Files changed (100) hide show
  1. package/CHANGELOG.md +234 -0
  2. package/COMPATIBILITY.md +231 -0
  3. package/MIGRATION.md +344 -0
  4. package/README.md +464 -265
  5. package/dist/address.d.ts +46 -0
  6. package/dist/annotation-selection.d.ts +32 -0
  7. package/dist/budget.d.ts +29 -0
  8. package/dist/classify.d.ts +15 -0
  9. package/dist/client.d.ts +938 -165
  10. package/dist/config.d.ts +115 -0
  11. package/dist/constants.d.ts +85 -0
  12. package/dist/document.d.ts +11 -0
  13. package/dist/effect.d.ts +22 -0
  14. package/dist/executor.d.ts +9 -0
  15. package/dist/exposure.d.ts +21 -0
  16. package/dist/guards.d.ts +2 -0
  17. package/dist/hooks.d.ts +16 -0
  18. package/dist/ids.d.ts +19 -0
  19. package/dist/index.d.ts +55 -49
  20. package/dist/index.js +3750 -1293
  21. package/dist/normalize.d.ts +9 -0
  22. package/dist/operation-sensitivity.d.ts +729 -0
  23. package/dist/operation.d.ts +145 -0
  24. package/dist/operations/catalogs-list-billing-profiles.d.ts +16 -0
  25. package/dist/operations/catalogs-list-nas.d.ts +25 -0
  26. package/dist/operations/catalogs-list-pops.d.ts +14 -0
  27. package/dist/operations/contracts-check-connection.d.ts +56 -0
  28. package/dist/operations/contracts-list-services.d.ts +103 -0
  29. package/dist/operations/contracts-list-status-reasons.d.ts +15 -0
  30. package/dist/operations/contracts-list.d.ts +52 -0
  31. package/dist/operations/contracts-update-status.d.ts +41 -0
  32. package/dist/operations/contracts-update.d.ts +39 -0
  33. package/dist/operations/coverage-check-address.d.ts +46 -0
  34. package/dist/operations/coverage-check.d.ts +43 -0
  35. package/dist/operations/coverage-list-gateways.d.ts +16 -0
  36. package/dist/operations/crm-contracts-create-by-cpf-cnpj.d.ts +97 -0
  37. package/dist/operations/crm-contracts-create.d.ts +221 -0
  38. package/dist/operations/crm-contracts-list.d.ts +50 -0
  39. package/dist/operations/crm-customers-create.d.ts +165 -0
  40. package/dist/operations/crm-customers-update-status.d.ts +41 -0
  41. package/dist/operations/customers-list.d.ts +104 -0
  42. package/dist/{endpoints/ura/lookup-customer.d.ts → operations/customers-search.d.ts} +56 -46
  43. package/dist/operations/documents-add.d.ts +29 -0
  44. package/dist/operations/documents-list.d.ts +31 -0
  45. package/dist/operations/experimental-annotations-list.d.ts +67 -0
  46. package/dist/operations/invoices-list.d.ts +148 -0
  47. package/dist/operations/maintenance-list.d.ts +35 -0
  48. package/dist/operations/occurrences-create.d.ts +125 -0
  49. package/dist/operations/occurrences-list-methods.d.ts +14 -0
  50. package/dist/operations/occurrences-list-types.d.ts +20 -0
  51. package/dist/operations/occurrences-list.d.ts +127 -0
  52. package/dist/{endpoints/ura/list-plans.d.ts → operations/plans-list.d.ts} +33 -23
  53. package/dist/operations/pre-registrations-create.d.ts +276 -0
  54. package/dist/operations/pre-registrations-list-due-days.d.ts +15 -0
  55. package/dist/operations/pre-registrations-list-plans.d.ts +24 -0
  56. package/dist/operations/pre-registrations-list-sellers.d.ts +16 -0
  57. package/dist/operations/services-add-generic.d.ts +52 -0
  58. package/dist/operations/services-add-tv.d.ts +47 -0
  59. package/dist/operations/services-change-plan.d.ts +40 -0
  60. package/dist/operations/services-remove-generic.d.ts +28 -0
  61. package/dist/operations/services-remove-tv.d.ts +29 -0
  62. package/dist/operations/work-orders-get.d.ts +99 -0
  63. package/dist/operations/work-orders-list-comments.d.ts +34 -0
  64. package/dist/operations/work-orders-list-reasons.d.ts +20 -0
  65. package/dist/operations/work-orders-list.d.ts +81 -0
  66. package/dist/path.d.ts +13 -0
  67. package/dist/raw-request.d.ts +26 -0
  68. package/dist/request.d.ts +28 -0
  69. package/dist/result.d.ts +113 -41
  70. package/dist/retry.d.ts +34 -0
  71. package/dist/sensitivity.d.ts +89 -4
  72. package/dist/tolerant.d.ts +21 -0
  73. package/dist/validation.d.ts +3 -0
  74. package/package.json +6 -3
  75. package/dist/endpoint.d.ts +0 -66
  76. package/dist/endpoints/crm/address.d.ts +0 -20
  77. package/dist/endpoints/crm/create-contract.d.ts +0 -109
  78. package/dist/endpoints/crm/create-customer.d.ts +0 -65
  79. package/dist/endpoints/crm/update-customer-status.d.ts +0 -43
  80. package/dist/endpoints/os/list-occurrence-reasons.d.ts +0 -24
  81. package/dist/endpoints/os/list-occurrence-types.d.ts +0 -25
  82. package/dist/endpoints/precadastro/list-due-days.d.ts +0 -19
  83. package/dist/endpoints/precadastro/list-sellers.d.ts +0 -21
  84. package/dist/endpoints/suporte/add-customer-document.d.ts +0 -24
  85. package/dist/endpoints/suporte/list-customer-documents.d.ts +0 -25
  86. package/dist/endpoints/ura/check-coverage.d.ts +0 -46
  87. package/dist/endpoints/ura/list-annotations.d.ts +0 -32
  88. package/dist/endpoints/ura/list-clients.d.ts +0 -58
  89. package/dist/endpoints/ura/list-contracts.d.ts +0 -45
  90. package/dist/endpoints/ura/list-invoices.d.ts +0 -107
  91. package/dist/endpoints/ura/list-nas.d.ts +0 -29
  92. package/dist/endpoints/ura/list-occurrence-methods.d.ts +0 -19
  93. package/dist/endpoints/ura/list-payment-carriers.d.ts +0 -20
  94. package/dist/endpoints/ura/list-pops.d.ts +0 -19
  95. package/dist/endpoints/ura/list-service-orders.d.ts +0 -64
  96. package/dist/endpoints/ura/open-ticket.d.ts +0 -81
  97. package/dist/errors.d.ts +0 -59
  98. package/dist/schema/parse.d.ts +0 -19
  99. package/dist/schema/paths.d.ts +0 -38
  100. package/dist/transport.d.ts +0 -65
package/dist/result.d.ts CHANGED
@@ -1,55 +1,127 @@
1
- /** Normalized failure category returned by every SDK method. */
2
- export type SgpErrorCode = "UNAUTHORIZED" | "ROUTE_NOT_ALLOWED" | "NOT_FOUND" | "METHOD_NOT_ALLOWED" | "VALIDATION" | "SCHEMA_MISMATCH" | "UPSTREAM" | "TIMEOUT" | "NETWORK" | "UNKNOWN";
3
- /** Normalized error. Never carries credentials, query strings, raw bodies or fetch exception messages. */
4
- export interface SgpError {
5
- /** HTTP status, or 0 when no response was received. */
1
+ /** Stable failure category of every 2.0 method. Branch on this, never on `message`. */
2
+ export type SgpErrorCode = "INVALID_INPUT" | "UNAUTHORIZED" | "FORBIDDEN" | "RATE_LIMITED" | "ROUTE_NOT_ALLOWED" | "NOT_FOUND" | "REJECTED" | "UPSTREAM" | "NETWORK" | "TIMEOUT" | "ABORTED" | "INVALID_RESPONSE";
3
+ /**
4
+ * What the SDK can affirm about the requested change of a write: `"none"` when it can affirm the
5
+ * change was not applied, `"unknown"` otherwise. Reads carry no effect.
6
+ */
7
+ export type Effect = "none" | "unknown";
8
+ /**
9
+ * Body of a captured response, as a discriminated value. `json` and `text` hold the decoded content
10
+ * (not the wire bytes); `unavailable` means the body started but could not be read to the end.
11
+ * `withheld` is a body the SDK received and deliberately did not keep: only
12
+ * `experimental.annotations.list` produces it, because its body holds other customers' notes.
13
+ */
14
+ export type ResponseBody = {
15
+ kind: "json";
16
+ value: unknown;
17
+ } | {
18
+ kind: "text";
19
+ text: string;
20
+ } | {
21
+ kind: "empty";
22
+ } | {
23
+ kind: "unavailable";
24
+ reason: "timeout" | "aborted" | "network";
25
+ } | {
26
+ kind: "withheld";
27
+ reason: "bulk-privacy";
28
+ };
29
+ /** The HTTP response SGP sent: status, headers (lowercased names) and body. */
30
+ export interface CapturedResponse {
31
+ /** HTTP status code SGP answered with. */
6
32
  status: number;
33
+ /**
34
+ * Header values as received, except that the credentials of the client are replaced by
35
+ * `<redacted>`: the value of any `token`/`app` parameter of a query or fragment, and the exact
36
+ * token or app (plain or URL-encoded) wherever it appears, when it has at least 8 characters.
37
+ */
38
+ headers: Readonly<Record<string, string>>;
39
+ /** The body as read; see {@link ResponseBody} for what each kind means. */
40
+ body: ResponseBody;
41
+ }
42
+ /** SGP's own error fields, values exactly as received. Only the keys present in the body appear. */
43
+ export interface SgpErrorFields {
44
+ /** SGP's `detail` text, as received. */
45
+ detail?: unknown;
46
+ /** SGP's `msg` text, as received. */
47
+ msg?: unknown;
48
+ /** SGP's `error` text, as received. */
49
+ error?: unknown;
50
+ /** SGP's `errors`, as received: an object of field errors or an array of texts. */
51
+ errors?: unknown;
52
+ }
53
+ /** Normalized failure of a method. Never carries credentials, URLs or thrown objects. */
54
+ export interface SgpError {
55
+ /** Stable failure category; branch on this. */
7
56
  code: SgpErrorCode;
8
57
  /** Written by the SDK, in English. */
9
58
  message: string;
59
+ /** Name of the operation that failed, e.g. `customers.list`. */
60
+ operation: string;
61
+ /** Operation-specific code, only where there is per-operation evidence. */
62
+ reason?: string;
63
+ /** What is known about the remote effect; set by writes only. */
64
+ effect?: Effect;
65
+ /** Projection of the SGP error fields found in the response body. */
66
+ sgp?: SgpErrorFields;
10
67
  /**
11
- * Text from SGP's error body, copied verbatim (it can echo values from the request; the SDK adds
12
- * nothing to it). Precedence: `detail` string, then non-empty `msg` string, then `errors`
13
- * (array items, or `"key: value"` pairs from an object, joined by `"; "`), then non-empty
14
- * `error` string. 401/403 are classified by it.
68
+ * On `INVALID_RESPONSE`: the paths that broke the contract, never values. On `INVALID_INPUT`:
69
+ * only when the SDK names the broken field (a `cpfcnpj` in a format no storing write accepts:
70
+ * `"cpfcnpj: expected ..."`); most local refusals carry none.
15
71
  */
16
- detail?: string;
17
- /** Request path only, without query string. */
18
- endpoint: string;
72
+ issues?: readonly string[];
19
73
  }
20
- /** A non-key field whose type did not match the schema; reports type names, never values. */
74
+ /** A hook that threw. Only its name and the attempt it ran on are kept, never the thrown value. */
75
+ export interface Diagnostic {
76
+ /** Which hook threw. */
77
+ hook: "onRequest" | "onResponse" | "onError";
78
+ /** Attempt number (1-based) during which the hook ran. */
79
+ occurrence: number;
80
+ }
81
+ /** Fields every result carries, on success and on failure. */
82
+ export interface ResultBase {
83
+ /** Requests the SDK started: 0 when refused locally, 1 for the first transport call. */
84
+ attempts: number;
85
+ /** Present only when a hook failed. */
86
+ diagnostics?: readonly Diagnostic[];
87
+ }
88
+ /**
89
+ * A field that did not have the type the method expects but is not essential to the response. The
90
+ * field left `data` and stays untouched in `response.body`, unless that body is `withheld` (then it
91
+ * is not recoverable). Type names only, never values.
92
+ */
21
93
  export interface SchemaWarning {
94
+ /** Where the mismatch is, with real indices: `clientes[0].contratos[1].status`. */
22
95
  path: string;
96
+ /**
97
+ * The field that is absent from `data` because of it. Equal to `path`, except when the mismatch is
98
+ * an array element: the whole array field is dropped (`clientes[0].contatos.emails`).
99
+ */
100
+ dropped: string;
101
+ /** Type the method expects (`string`, or `number | string` when several are accepted). */
23
102
  expected: string;
103
+ /** Type that arrived: `string`, `number`, `boolean`, `null`, `undefined`, `array` or `object`. */
24
104
  received: string;
25
105
  }
26
- /** Outcome of every SDK method; methods never throw for network, HTTP or schema failures. */
27
- export type SgpResult<T> = {
28
- success: true;
106
+ /** Successful call. `response` is the raw HTTP response the data came from. */
107
+ export interface SgpSuccess<T> extends ResultBase {
108
+ /** Discriminant: `true` on success. */
109
+ ok: true;
110
+ /** What the method returns, decoded from the response. */
29
111
  data: T;
30
- warnings?: SchemaWarning[];
31
- } | {
32
- success: false;
112
+ /** The HTTP response `data` came from. */
113
+ response: CapturedResponse;
114
+ /** Present only when a non-essential field was dropped from `data`; see {@link SchemaWarning}. */
115
+ warnings?: readonly SchemaWarning[];
116
+ }
117
+ /** Failed call. `response` is `null` when no HTTP response was available. */
118
+ export interface SgpFailure extends ResultBase {
119
+ /** Discriminant: `false` on failure. */
120
+ ok: false;
121
+ /** Why the call failed. */
33
122
  error: SgpError;
34
- };
35
- /**
36
- * Whether SGP applied a failed write: `"not_applied"` for a 4xx or a request rejected locally before
37
- * being sent (`VALIDATION`, status 0), `"unknown"` for everything else. The exception is SGP's
38
- * generic exception wrapper, a 4xx (in practice 400) whose body `errors` is an array (e.g.
39
- * `"Ocorreu um erro: ..."`): SGP may have failed after applying the write, so it is `"unknown"`.
40
- * 401/403/404/405/422 stay `"not_applied"`.
41
- */
42
- export type WriteOutcome = "not_applied" | "unknown";
43
- /** Normalized write error; `outcome` says whether the write may have taken effect. */
44
- export interface SgpWriteError extends SgpError {
45
- outcome: WriteOutcome;
46
- }
47
- /** Outcome of every SDK write method; like reads, they never throw for network, HTTP or schema failures. */
48
- export type SgpWriteResult<T> = {
49
- success: true;
50
- data: T;
51
- warnings?: SchemaWarning[];
52
- } | {
53
- success: false;
54
- error: SgpWriteError;
55
- };
123
+ /** The HTTP response received, or `null` when none was (refused locally, or the transport failed). */
124
+ response: CapturedResponse | null;
125
+ }
126
+ /** Outcome of every 2.0 method: expected failures are returned, never thrown. */
127
+ export type SgpResult<T> = SgpSuccess<T> | SgpFailure;
@@ -0,0 +1,34 @@
1
+ import type { SgpFailure } from "./result.js";
2
+ /**
3
+ * INTERNAL. The clock, the jitter and the wait of a call, injectable so retry timing is testable
4
+ * without real sleeps. Consumers never see it.
5
+ */
6
+ export interface Runtime {
7
+ /** Epoch milliseconds. */
8
+ now: () => number;
9
+ /** In [0, 1). */
10
+ random: () => number;
11
+ /**
12
+ * Resolves after `ms`, or as soon as `signal` aborts (the executor then reads the budget's stop
13
+ * cause). Must release its timer and listener either way.
14
+ */
15
+ sleep: (ms: number, signal: AbortSignal) => Promise<void>;
16
+ }
17
+ export declare const defaultRuntime: Runtime;
18
+ /**
19
+ * Whether the failure itself is the kind a repeat can fix: `RATE_LIMITED`, any `NETWORK`
20
+ * (the transport broke before or while reading the response, so nothing came of the attempt) and
21
+ * `UPSTREAM` with status 502, 503 or 504. A plain 500 is not on the list: it is as likely a
22
+ * deterministic bug of the route as a blip. The caller must still check the budget's stop cause.
23
+ */
24
+ export declare const isTransientFailure: (failure: SgpFailure) => boolean;
25
+ /**
26
+ * Wait before retry number `retryNumber` (1-based): "equal jitter" over an exponential ceiling,
27
+ * half fixed and half random, so a burst of clients spreads out without ever waiting zero.
28
+ */
29
+ export declare const backoffMs: (retryNumber: number, random: () => number) => number;
30
+ /**
31
+ * Milliseconds the server asked to wait: whole seconds, or an HTTP date relative to `now`. A past
32
+ * date is `0`. `undefined` when the header is absent or unreadable (the backoff then decides).
33
+ */
34
+ export declare const parseRetryAfter: (value: string | null, now: number) => number | undefined;
@@ -1,7 +1,92 @@
1
+ import type { Diagnostic, Effect, SchemaWarning, SgpErrorCode, SgpResult } from "./result.js";
1
2
  /**
2
- * Returns a shallow copy of `obj` without `keys`, typed accordingly.
3
+ * The keys of one kind of object that hold sensitive values. The same declaration describes the
4
+ * request fields (`input`) and the fields of the 2xx body (`output`, same shape as `data` and as
5
+ * `response.body.value`) of an operation.
6
+ */
7
+ export interface SensitivityScope {
8
+ /**
9
+ * Where the objects are, in {@link pick} path syntax: `""` for the root object,
10
+ * `clientes[].contratos[]` for each contract of each customer.
11
+ */
12
+ path: string;
13
+ /** Credentials and network identifiers: Central/PPPoE logins and passwords, Wi-Fi, MAC, IP... */
14
+ secretKeys: readonly string[];
15
+ /** Personal data of a customer: name, document, address, contacts... A key covers its subtree. */
16
+ personalKeys: readonly string[];
17
+ }
18
+ /**
19
+ * What an operation declares as sensitive. Keys not listed are not "safe": the SDK treats every
20
+ * field it does not know as potentially sensitive, and so should the consumer (use {@link pick}).
21
+ */
22
+ export interface OperationSensitivity {
23
+ /** Fields of the request. */
24
+ input: readonly SensitivityScope[];
25
+ /** Fields of the 2xx body. */
26
+ output: readonly SensitivityScope[];
27
+ }
28
+ /**
29
+ * Allowlist projection: a copy of `source` holding only the paths of `allowlist`. This is the way
30
+ * to hand anything to a log, a tool or an MCP server; never pass a result, `data` or `response`
31
+ * on as is.
32
+ *
33
+ * `source` is a `data` object or a whole result (then paths start at `data`, `error`, `response`,
34
+ * `attempts`...). Path syntax: keys joined by `.`, `[]` after a key for each element of an array
35
+ * (`clientes[].contratos[].id`), `[].id` for a root array. A path naming an object or array takes
36
+ * its whole subtree, which is the caller's explicit choice, with one exception: naming `response`
37
+ * alone takes neither `response.body` nor `response.headers`; those two come out only when a path
38
+ * names them exactly or goes below them (`response.body`, `response.headers.content-type`). Every
39
+ * key not named never comes out. A malformed path picks nothing. Only own, JSON-like values are
40
+ * copied. Depth is not bounded: do not hand it untrusted, arbitrarily deep input.
41
+ *
42
+ * Returns `{}` (or `[]`) when nothing matches.
43
+ */
44
+ export declare const pick: (source: unknown, allowlist: readonly string[]) => unknown;
45
+ /**
46
+ * What {@link toSafeLog} keeps of a result. Nothing of `data`, of the response (body and headers
47
+ * included) or of SGP's own error text.
48
+ */
49
+ export interface SafeLog {
50
+ /** Whether the call succeeded. */
51
+ ok: boolean;
52
+ /** Requests the SDK started: 0 when refused locally. */
53
+ attempts: number;
54
+ /** Hooks that threw: name and attempt, never the thrown value. */
55
+ diagnostics?: readonly Diagnostic[];
56
+ /** Fields dropped from `data`: paths and type names, never values. */
57
+ warnings?: readonly SchemaWarning[];
58
+ /** Only the status of the HTTP response; no body, no headers. */
59
+ response?: {
60
+ /** HTTP status SGP answered with. */
61
+ status: number;
62
+ };
63
+ /** The failure, without SGP's own text. */
64
+ error?: {
65
+ /** Stable failure category. */
66
+ code: SgpErrorCode;
67
+ /** Written by the SDK, never by SGP. */
68
+ message: string;
69
+ /** Name of the operation that failed. */
70
+ operation: string;
71
+ /** Operation-specific code, where there is evidence for it. */
72
+ reason?: string;
73
+ /** What is known about the remote effect of a write. */
74
+ effect?: Effect;
75
+ /** Paths that broke the contract, never values. */
76
+ issues?: readonly string[];
77
+ /** Names of the SGP error fields that came (`detail`, `errors`...); their values stay out. */
78
+ sgpFields?: readonly string[];
79
+ };
80
+ }
81
+ /**
82
+ * A copy of a success or failure that is meant to be logged: outcome, attempts, status, error
83
+ * code, reason, effect and the names of the SGP fields that came. No `data`, no `response.body`,
84
+ * no headers, no value of SGP's error text (`error.sgp`, which echoes what was sent), and no
85
+ * credentials.
3
86
  *
4
- * Meant for the `secretKeys` / `personalKeys` tuples of an endpoint, so callers can drop sensitive
5
- * fields before logging or forwarding an item. Does not mutate `obj`.
87
+ * An aid, not a guarantee: it protects only what goes through it. `console.log(result)`,
88
+ * `structuredClone(result)`, a logger that walks the object, or any copy made before this call
89
+ * still sees everything. Log `toSafeLog(result)`, never the result. To log or send part of `data`,
90
+ * use {@link pick} with an explicit allowlist.
6
91
  */
7
- export declare const omitSensitive: <T extends object, K extends keyof T>(obj: T, keys: readonly K[]) => Omit<T, K>;
92
+ export declare const toSafeLog: (result: SgpResult<unknown>) => SafeLog;
@@ -0,0 +1,21 @@
1
+ import type { z } from "zod";
2
+ import type { DecodeOutcome } from "./operation.js";
3
+ import type { ResponseBody } from "./result.js";
4
+ /**
5
+ * The tolerant reader: validates a JSON body with `schema` and applies the fidelity policy.
6
+ *
7
+ * - A mismatch on one of the `invariants` (or anywhere the body cannot be read at all) is
8
+ * `{ ok: false }`: the whole response is outside the contract.
9
+ * - Any other mismatch is tolerated: the offending field leaves its typed position (the nearest
10
+ * enclosing object property when the issue sits on an array element), a warning with the precise
11
+ * location and type names (never values) is returned, and the evidence is not touched because
12
+ * this works on a copy.
13
+ * - An issue inside an array whose elements carry an invariant (an element that is not an object)
14
+ * is an invariant failure; the array is never dropped silently.
15
+ * - Unknown keys are kept by the schema (loose objects), and nothing is ever invented.
16
+ *
17
+ * Invariants are declared per operation as paths: `clientes[].id`, with `[]` for any index. List the
18
+ * containers that must be readable too (`clientes`, `paginacao`), since a container is dropped
19
+ * like any other field unless it is an invariant.
20
+ */
21
+ export declare const tolerantDecoder: <S extends z.ZodType>(schema: S, invariants: readonly string[]) => (body: ResponseBody) => DecodeOutcome<z.output<S>>;
@@ -0,0 +1,3 @@
1
+ import { z } from "zod";
2
+ /** A string with something in it: not empty, not only whitespace. */
3
+ export declare const nonBlank: z.ZodString;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sgp-sdk",
3
- "version": "1.2.0",
3
+ "version": "2.0.0-beta.2",
4
4
  "description": "Unofficial TypeScript client for the SGP (TSMX) ISP ERP HTTP API, with normalized errors and explicit write outcomes. Not affiliated with TSMX.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,7 +12,10 @@
12
12
  }
13
13
  },
14
14
  "files": [
15
- "dist"
15
+ "dist",
16
+ "MIGRATION.md",
17
+ "COMPATIBILITY.md",
18
+ "CHANGELOG.md"
16
19
  ],
17
20
  "engines": {
18
21
  "node": ">=22"
@@ -23,7 +26,7 @@
23
26
  "test": "bun test",
24
27
  "lint": "biome check .",
25
28
  "typecheck": "tsc --noEmit",
26
- "check:consumer-types": "bun run build && tsc -p tests/consumer-types/tsconfig.json"
29
+ "check:consumer-types": "bun run build && tsc -p tests/consumer-types/tsconfig.json && tsc -p tests/consumer-types/tsconfig.bundler.json"
27
30
  },
28
31
  "dependencies": {
29
32
  "zod": "^4"
@@ -1,66 +0,0 @@
1
- import type { z } from "zod";
2
- import type { SgpResult, SgpWriteResult } from "./result.js";
3
- import { type ParamValue, type RequestSpec, type SgpClientConfig, type SgpFile } from "./transport.js";
4
- /** Static description of one SGP route: how to call it, how to parse it and what is sensitive. */
5
- export interface EndpointDefinition<S extends z.ZodType> {
6
- method: "GET" | "POST";
7
- /** Request path starting with `/`; also the `endpoint` of every error. */
8
- path: string;
9
- schema: S;
10
- /** Normalized paths of the required, strict fields (see `parseResponse`). */
11
- keyFields: readonly string[];
12
- /** Normalized path of the response items that carry sensitive keys, e.g. `clientes[]`. */
13
- itemPath: string;
14
- /** Keys of an item holding secrets (passwords, MACs, links with embedded token). */
15
- secretKeys: readonly string[];
16
- /** Keys of an item holding personal data (CPF/CNPJ, phone, e-mail, address, name). */
17
- personalKeys: readonly string[];
18
- }
19
- /**
20
- * Static description of one SGP write route. Like {@link EndpointDefinition}, but `schema` is the
21
- * success body: a 2xx only counts as success when it validates (key fields present, right type).
22
- */
23
- export interface WriteEndpointDefinition<S extends z.ZodType> {
24
- kind: "write";
25
- method: "POST" | "PUT";
26
- /** Request path template, e.g. `/api/crm/cliente/{cliente_id}/contratos/`; also the `endpoint` of every error. */
27
- path: string;
28
- schema: S;
29
- /** Normalized paths of the required, strict fields (see `parseResponse`). */
30
- keyFields: readonly string[];
31
- /** Normalized path of the response items that carry sensitive keys. */
32
- itemPath: string;
33
- /** Keys of an item holding secrets. */
34
- secretKeys: readonly string[];
35
- /** Keys of an item holding personal data. */
36
- personalKeys: readonly string[];
37
- }
38
- /** Inputs of one write call: values for the path placeholders, the request params and any files. */
39
- export interface WriteCall {
40
- pathParams?: Record<string, string | number>;
41
- params?: Record<string, ParamValue | undefined>;
42
- files?: Record<string, SgpFile>;
43
- }
44
- /**
45
- * Sends the request described by `def` and parses the response with its schema.
46
- *
47
- * Never throws: transport and HTTP failures come back as `{ success: false, error }` and a body
48
- * that does not match the schema as `SCHEMA_MISMATCH`.
49
- */
50
- export declare const callEndpoint: <S extends z.ZodType>(config: SgpClientConfig, def: EndpointDefinition<S>, params?: RequestSpec["params"], pathParams?: RequestSpec["pathParams"]) => Promise<SgpResult<z.output<S>>>;
51
- /**
52
- * Sends the write described by `def` and tells whether SGP applied it.
53
- *
54
- * Never throws. Success is a 2xx whose body validates against `def.schema`. A failure carries an
55
- * `outcome`:
56
- * - `"not_applied"`: SGP answered 4xx and rejected the request, or the SDK rejected it locally before
57
- * sending (invalid path params, `VALIDATION` with status 0);
58
- * - `"unknown"`: no response (timeout, network), 5xx, 3xx (redirects are never followed), a 4xx
59
- * whose body `errors` is an array (SGP's generic exception wrapper, except 401/403/404/405/422),
60
- * or a 2xx that is not a valid success (empty or non-JSON body, key field missing). The 2xx case
61
- * is a `VALIDATION` error with the real HTTP status and, for a JSON body, SGP's own text
62
- * (`detail`/`msg`/`errors`/`error`) or else the failing paths.
63
- *
64
- * Never retried by the SDK. With `outcome: "unknown"`, check the state in SGP before repeating.
65
- */
66
- export declare const callWriteEndpoint: <S extends z.ZodType>(config: SgpClientConfig, def: WriteEndpointDefinition<S>, call?: WriteCall) => Promise<SgpWriteResult<z.output<S>>>;
@@ -1,20 +0,0 @@
1
- /**
2
- * Address as SGP takes it. Pass it once: the SDK serializes it both nested (`endereco`) and as
3
- * loose fields (`logradouro`, `numero`, ...), which are the two formats the CRM routes read.
4
- */
5
- export interface SgpAddress {
6
- logradouro: string;
7
- numero?: string | number;
8
- complemento?: string;
9
- bairro: string;
10
- cidade: string;
11
- cep: string;
12
- uf: string;
13
- pais?: string;
14
- pontoreferencia?: string;
15
- /** Map position, `"lat,lng"`. */
16
- map_ll?: string;
17
- condominio?: string | number;
18
- }
19
- /** The address as a plain record with the same keys and no `undefined` ones. */
20
- export declare const flatAddress: (address: SgpAddress) => Record<string, string | number>;
@@ -1,109 +0,0 @@
1
- import { z } from "zod";
2
- import type { WriteEndpointDefinition } from "../../endpoint.js";
3
- import type { ParamValue } from "../../transport.js";
4
- import { type SgpAddress } from "./address.js";
5
- /** SGP's billing methods, by the `forma_cobranca_codigo` it takes. */
6
- export declare const formaCobrancaCodigo: {
7
- readonly boleto: 1;
8
- readonly debitoAutomatico: 2;
9
- readonly carne: 3;
10
- readonly cobrancaRecorrente: 4;
11
- readonly pix: 6;
12
- };
13
- /** A valid `forma_cobranca_codigo` of `POST /api/crm/cliente/{cliente_id}/contratos/`. */
14
- export type FormaCobrancaCodigo = (typeof formaCobrancaCodigo)[keyof typeof formaCobrancaCodigo];
15
- /**
16
- * SGP's equipment acquisition modes, by the `modoaquisicao` it takes: 0 Próprio and 1 Comodato.
17
- * SGP rejects any other value (2 included), although its Postman collection lists 1 and 2.
18
- */
19
- export declare const modoAquisicao: {
20
- readonly proprio: 0;
21
- readonly comodato: 1;
22
- };
23
- /** A valid `modoaquisicao` of `POST /api/crm/cliente/{cliente_id}/contratos/`. */
24
- export type ModoAquisicao = (typeof modoAquisicao)[keyof typeof modoAquisicao];
25
- /**
26
- * Success body of `POST /api/crm/cliente/{cliente_id}/contratos/`: the new contract ID, SGP's
27
- * message and the customer's name.
28
- */
29
- export declare const createContractSchema: z.ZodObject<{
30
- message: z.ZodNullable<z.ZodOptional<z.ZodString>>;
31
- clientecontrato: z.ZodNumber;
32
- cliente: z.ZodNullable<z.ZodOptional<z.ZodString>>;
33
- }, z.core.$strip>;
34
- /** Key fields of `crm/cliente/{cliente_id}/contratos/`: required and strict; a 2xx without them is not a success. */
35
- export declare const createContractKeyFields: readonly ["clientecontrato"];
36
- /** Normalized path of the created contract in the response (the root object). */
37
- export declare const contractCreatedItemPath = "";
38
- /** Keys of the response holding secrets (none in `crm/cliente/{cliente_id}/contratos/`). */
39
- export declare const contractCreatedSecretKeys: readonly [];
40
- /** Keys of the response holding personal data: `cliente` is the customer's name. */
41
- export declare const contractCreatedPersonalKeys: readonly ["cliente"];
42
- /** Parsed response of `POST /api/crm/cliente/{cliente_id}/contratos/`. */
43
- export type CreateContractResponse = z.output<typeof createContractSchema>;
44
- /**
45
- * Params of `POST /api/crm/cliente/{cliente_id}/contratos/`; `cliente_id` goes in the path.
46
- * `login`, `senha`, `central_login`, `central_senha`, the addresses and the network fields
47
- * (`ip`, `mac`, `mac_dhcp`) are secret or personal data.
48
- */
49
- export interface CreateContractParams {
50
- pop_id: number;
51
- plano_id: number;
52
- /** Payer or financial responsible. */
53
- portador_id: number;
54
- forma_cobranca_codigo: FormaCobrancaCodigo;
55
- /** Due day registered in SGP. */
56
- vencimento_dia: number;
57
- /** Sent nested and also as the loose fields (`logradouro`, `numero`, ...) SGP reads. */
58
- endereco_instalacao: SgpAddress;
59
- endereco_cobranca: SgpAddress;
60
- /** PPPoE login and password: SGP requires them for an internet service. */
61
- login?: string;
62
- senha?: string;
63
- modoaquisicao?: ModoAquisicao;
64
- /** Name of the NAS. */
65
- nas?: string;
66
- /** Exempt percentage. */
67
- isento?: number;
68
- autocobranca?: boolean;
69
- servicodesc?: string;
70
- observacao?: string;
71
- vendedor_id?: number;
72
- /** 1 = percentage, 2 = fixed amount. */
73
- comissao_tipo?: 1 | 2;
74
- comissao?: number;
75
- /** Contract group for printing. */
76
- contrato_id?: number;
77
- fidelidade_id?: number;
78
- midia_id?: number;
79
- central_login?: string;
80
- central_senha?: string;
81
- ip?: string;
82
- ippool_id?: number;
83
- mac_dhcp?: string;
84
- mac?: string;
85
- logins_simult?: number;
86
- splitter_id?: number;
87
- splitter_port?: number;
88
- tipo_equipamento?: string;
89
- usuarioalt_id?: number;
90
- /** Opens the installation service order, without a date. */
91
- os_instalacao?: boolean;
92
- /** Text of the installation occurrence. */
93
- conteudo?: string;
94
- instalacao_quantidade_parcelas?: number;
95
- instalacao_preco?: number;
96
- instalacao_desconto?: number;
97
- instalacao_entrada?: number;
98
- instalacao_entrada_forma?: number;
99
- instalacao_parcela_forma?: number;
100
- instalacao_portador?: number;
101
- }
102
- /**
103
- * Request body of the contract route: the params, with both addresses nested and the installation
104
- * one also as loose fields beside them (SGP describes those as "installation and billing").
105
- * `undefined` address keys are omitted in both formats.
106
- */
107
- export declare const toContractBody: (params: CreateContractParams) => Record<string, ParamValue | undefined>;
108
- /** Definition of `POST /api/crm/cliente/{cliente_id}/contratos/` (trailing slash required by the token whitelist). */
109
- export declare const createContractDefinition: WriteEndpointDefinition<typeof createContractSchema>;
@@ -1,65 +0,0 @@
1
- import { z } from "zod";
2
- import type { WriteEndpointDefinition } from "../../endpoint.js";
3
- import type { ParamValue } from "../../transport.js";
4
- import { type SgpAddress } from "./address.js";
5
- /** Success body of `POST /api/crm/cliente/{F|J}`: the new CRM customer ID and SGP's message. */
6
- export declare const createCustomerSchema: z.ZodObject<{
7
- cliente_id: z.ZodNumber;
8
- message: z.ZodNullable<z.ZodOptional<z.ZodString>>;
9
- }, z.core.$strip>;
10
- /** Key fields of `crm/cliente/{F|J}`: required and strict; a 2xx without them is not a success. */
11
- export declare const createCustomerKeyFields: readonly ["cliente_id"];
12
- /** Normalized path of the created customer in the response (the root object). */
13
- export declare const customerCreatedItemPath = "";
14
- /** Keys of the response holding secrets (none in `crm/cliente/{F|J}`). */
15
- export declare const customerCreatedSecretKeys: readonly [];
16
- /** Keys of the response holding personal data: SGP's message carries the name and CPF/CNPJ. */
17
- export declare const customerCreatedPersonalKeys: readonly ["message"];
18
- /** Parsed response of `POST /api/crm/cliente/F` and `POST /api/crm/cliente/J`. */
19
- export type CreateCustomerResponse = z.output<typeof createCustomerSchema>;
20
- /** Params of `POST /api/crm/cliente/F` (individual). Name, CPF and address are personal data. */
21
- export interface CreateIndividualCustomerParams {
22
- nome: string;
23
- cpfcnpj: string;
24
- endereco: SgpAddress;
25
- email?: string;
26
- celular?: string;
27
- /** `"DD/MM/AAAA"`. */
28
- datanasc?: string;
29
- observacao?: string;
30
- rg?: string;
31
- rg_emissor?: string;
32
- sexo?: "M" | "F";
33
- /** C = married, S = single, V = widowed, D = divorced. */
34
- estadocivil?: "C" | "S" | "V" | "D";
35
- nomemae?: string;
36
- nomepai?: string;
37
- profissao?: string;
38
- nacionalidade?: string;
39
- naturalidade?: string;
40
- }
41
- /** Params of `POST /api/crm/cliente/J` (company). Name, CNPJ and address are personal data. */
42
- export interface CreateCompanyCustomerParams {
43
- nome: string;
44
- cpfcnpj: string;
45
- endereco: SgpAddress;
46
- nomefantasia?: string;
47
- respempresa?: string;
48
- respcpf?: string;
49
- insc_estadual?: string;
50
- insc_municipal?: string;
51
- email?: string;
52
- celular?: string;
53
- /** `"DD/MM/AAAA"`. */
54
- datafundacao?: string;
55
- observacao?: string;
56
- }
57
- /**
58
- * Request body of the customer routes: the params, with the address nested (`endereco`) and also
59
- * as loose fields beside them, as SGP reads both. `undefined` address keys are omitted in both.
60
- */
61
- export declare const toCustomerBody: (params: CreateIndividualCustomerParams | CreateCompanyCustomerParams) => Record<string, ParamValue | undefined>;
62
- /** Definition of `POST /api/crm/cliente/F` (individual customer). */
63
- export declare const createIndividualCustomerDefinition: WriteEndpointDefinition<typeof createCustomerSchema>;
64
- /** Definition of `POST /api/crm/cliente/J` (company customer). */
65
- export declare const createCompanyCustomerDefinition: WriteEndpointDefinition<typeof createCustomerSchema>;