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.
- package/CHANGELOG.md +234 -0
- package/COMPATIBILITY.md +231 -0
- package/MIGRATION.md +344 -0
- package/README.md +464 -265
- package/dist/address.d.ts +46 -0
- package/dist/annotation-selection.d.ts +32 -0
- package/dist/budget.d.ts +29 -0
- package/dist/classify.d.ts +15 -0
- package/dist/client.d.ts +938 -165
- package/dist/config.d.ts +115 -0
- package/dist/constants.d.ts +85 -0
- package/dist/document.d.ts +11 -0
- package/dist/effect.d.ts +22 -0
- package/dist/executor.d.ts +9 -0
- package/dist/exposure.d.ts +21 -0
- package/dist/guards.d.ts +2 -0
- package/dist/hooks.d.ts +16 -0
- package/dist/ids.d.ts +19 -0
- package/dist/index.d.ts +55 -49
- package/dist/index.js +3750 -1293
- package/dist/normalize.d.ts +9 -0
- package/dist/operation-sensitivity.d.ts +729 -0
- package/dist/operation.d.ts +145 -0
- package/dist/operations/catalogs-list-billing-profiles.d.ts +16 -0
- package/dist/operations/catalogs-list-nas.d.ts +25 -0
- package/dist/operations/catalogs-list-pops.d.ts +14 -0
- package/dist/operations/contracts-check-connection.d.ts +56 -0
- package/dist/operations/contracts-list-services.d.ts +103 -0
- package/dist/operations/contracts-list-status-reasons.d.ts +15 -0
- package/dist/operations/contracts-list.d.ts +52 -0
- package/dist/operations/contracts-update-status.d.ts +41 -0
- package/dist/operations/contracts-update.d.ts +39 -0
- package/dist/operations/coverage-check-address.d.ts +46 -0
- package/dist/operations/coverage-check.d.ts +43 -0
- package/dist/operations/coverage-list-gateways.d.ts +16 -0
- package/dist/operations/crm-contracts-create-by-cpf-cnpj.d.ts +97 -0
- package/dist/operations/crm-contracts-create.d.ts +221 -0
- package/dist/operations/crm-contracts-list.d.ts +50 -0
- package/dist/operations/crm-customers-create.d.ts +165 -0
- package/dist/operations/crm-customers-update-status.d.ts +41 -0
- package/dist/operations/customers-list.d.ts +104 -0
- package/dist/{endpoints/ura/lookup-customer.d.ts → operations/customers-search.d.ts} +56 -46
- package/dist/operations/documents-add.d.ts +29 -0
- package/dist/operations/documents-list.d.ts +31 -0
- package/dist/operations/experimental-annotations-list.d.ts +67 -0
- package/dist/operations/invoices-list.d.ts +148 -0
- package/dist/operations/maintenance-list.d.ts +35 -0
- package/dist/operations/occurrences-create.d.ts +125 -0
- package/dist/operations/occurrences-list-methods.d.ts +14 -0
- package/dist/operations/occurrences-list-types.d.ts +20 -0
- package/dist/operations/occurrences-list.d.ts +127 -0
- package/dist/{endpoints/ura/list-plans.d.ts → operations/plans-list.d.ts} +33 -23
- package/dist/operations/pre-registrations-create.d.ts +276 -0
- package/dist/operations/pre-registrations-list-due-days.d.ts +15 -0
- package/dist/operations/pre-registrations-list-plans.d.ts +24 -0
- package/dist/operations/pre-registrations-list-sellers.d.ts +16 -0
- package/dist/operations/services-add-generic.d.ts +52 -0
- package/dist/operations/services-add-tv.d.ts +47 -0
- package/dist/operations/services-change-plan.d.ts +40 -0
- package/dist/operations/services-remove-generic.d.ts +28 -0
- package/dist/operations/services-remove-tv.d.ts +29 -0
- package/dist/operations/work-orders-get.d.ts +99 -0
- package/dist/operations/work-orders-list-comments.d.ts +34 -0
- package/dist/operations/work-orders-list-reasons.d.ts +20 -0
- package/dist/operations/work-orders-list.d.ts +81 -0
- package/dist/path.d.ts +13 -0
- package/dist/raw-request.d.ts +26 -0
- package/dist/request.d.ts +28 -0
- package/dist/result.d.ts +113 -41
- package/dist/retry.d.ts +34 -0
- package/dist/sensitivity.d.ts +89 -4
- package/dist/tolerant.d.ts +21 -0
- package/dist/validation.d.ts +3 -0
- package/package.json +6 -3
- package/dist/endpoint.d.ts +0 -66
- package/dist/endpoints/crm/address.d.ts +0 -20
- package/dist/endpoints/crm/create-contract.d.ts +0 -109
- package/dist/endpoints/crm/create-customer.d.ts +0 -65
- package/dist/endpoints/crm/update-customer-status.d.ts +0 -43
- package/dist/endpoints/os/list-occurrence-reasons.d.ts +0 -24
- package/dist/endpoints/os/list-occurrence-types.d.ts +0 -25
- package/dist/endpoints/precadastro/list-due-days.d.ts +0 -19
- package/dist/endpoints/precadastro/list-sellers.d.ts +0 -21
- package/dist/endpoints/suporte/add-customer-document.d.ts +0 -24
- package/dist/endpoints/suporte/list-customer-documents.d.ts +0 -25
- package/dist/endpoints/ura/check-coverage.d.ts +0 -46
- package/dist/endpoints/ura/list-annotations.d.ts +0 -32
- package/dist/endpoints/ura/list-clients.d.ts +0 -58
- package/dist/endpoints/ura/list-contracts.d.ts +0 -45
- package/dist/endpoints/ura/list-invoices.d.ts +0 -107
- package/dist/endpoints/ura/list-nas.d.ts +0 -29
- package/dist/endpoints/ura/list-occurrence-methods.d.ts +0 -19
- package/dist/endpoints/ura/list-payment-carriers.d.ts +0 -20
- package/dist/endpoints/ura/list-pops.d.ts +0 -19
- package/dist/endpoints/ura/list-service-orders.d.ts +0 -64
- package/dist/endpoints/ura/open-ticket.d.ts +0 -81
- package/dist/errors.d.ts +0 -59
- package/dist/schema/parse.d.ts +0 -19
- package/dist/schema/paths.d.ts +0 -38
- package/dist/transport.d.ts +0 -65
package/dist/result.d.ts
CHANGED
|
@@ -1,55 +1,127 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export type SgpErrorCode = "UNAUTHORIZED" | "
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
-
|
|
17
|
-
/** Request path only, without query string. */
|
|
18
|
-
endpoint: string;
|
|
72
|
+
issues?: readonly string[];
|
|
19
73
|
}
|
|
20
|
-
/** A
|
|
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
|
-
/**
|
|
27
|
-
export
|
|
28
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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;
|
package/dist/retry.d.ts
ADDED
|
@@ -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;
|
package/dist/sensitivity.d.ts
CHANGED
|
@@ -1,7 +1,92 @@
|
|
|
1
|
+
import type { Diagnostic, Effect, SchemaWarning, SgpErrorCode, SgpResult } from "./result.js";
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
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
|
-
*
|
|
5
|
-
*
|
|
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
|
|
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>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sgp-sdk",
|
|
3
|
-
"version": "
|
|
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"
|
package/dist/endpoint.d.ts
DELETED
|
@@ -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>;
|