sgp-sdk 1.2.0 → 2.0.0-beta.1

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 (88) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/COMPATIBILITY.md +151 -0
  3. package/MIGRATION.md +283 -0
  4. package/README.md +422 -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 +661 -165
  10. package/dist/config.d.ts +115 -0
  11. package/dist/constants.d.ts +72 -0
  12. package/dist/effect.d.ts +22 -0
  13. package/dist/executor.d.ts +9 -0
  14. package/dist/exposure.d.ts +21 -0
  15. package/dist/guards.d.ts +2 -0
  16. package/dist/hooks.d.ts +16 -0
  17. package/dist/ids.d.ts +19 -0
  18. package/dist/index.d.ts +45 -49
  19. package/dist/index.js +2947 -1292
  20. package/dist/operation-sensitivity.d.ts +496 -0
  21. package/dist/operation.d.ts +139 -0
  22. package/dist/operations/catalogs-list-billing-profiles.d.ts +16 -0
  23. package/dist/operations/catalogs-list-nas.d.ts +25 -0
  24. package/dist/operations/catalogs-list-pops.d.ts +14 -0
  25. package/dist/operations/contracts-list-status-reasons.d.ts +15 -0
  26. package/dist/operations/contracts-list.d.ts +52 -0
  27. package/dist/operations/contracts-update-status.d.ts +41 -0
  28. package/dist/operations/contracts-update.d.ts +39 -0
  29. package/dist/operations/coverage-check.d.ts +42 -0
  30. package/dist/operations/crm-contracts-create-by-cpf-cnpj.d.ts +97 -0
  31. package/dist/operations/crm-contracts-create.d.ts +221 -0
  32. package/dist/operations/crm-contracts-list.d.ts +50 -0
  33. package/dist/operations/crm-customers-create.d.ts +155 -0
  34. package/dist/operations/crm-customers-update-status.d.ts +41 -0
  35. package/dist/operations/customers-list.d.ts +98 -0
  36. package/dist/{endpoints/ura/lookup-customer.d.ts → operations/customers-search.d.ts} +56 -46
  37. package/dist/operations/documents-add.d.ts +29 -0
  38. package/dist/operations/documents-list.d.ts +31 -0
  39. package/dist/operations/experimental-annotations-list.d.ts +67 -0
  40. package/dist/operations/invoices-list.d.ts +142 -0
  41. package/dist/operations/occurrences-create.d.ts +116 -0
  42. package/dist/operations/occurrences-list-methods.d.ts +14 -0
  43. package/dist/operations/occurrences-list-types.d.ts +20 -0
  44. package/dist/{endpoints/ura/list-plans.d.ts → operations/plans-list.d.ts} +33 -23
  45. package/dist/operations/pre-registrations-create.d.ts +253 -0
  46. package/dist/operations/pre-registrations-list-due-days.d.ts +15 -0
  47. package/dist/operations/pre-registrations-list-plans.d.ts +24 -0
  48. package/dist/operations/pre-registrations-list-sellers.d.ts +16 -0
  49. package/dist/operations/services-add-tv.d.ts +47 -0
  50. package/dist/operations/services-change-plan.d.ts +40 -0
  51. package/dist/operations/services-remove-tv.d.ts +29 -0
  52. package/dist/operations/work-orders-list-reasons.d.ts +20 -0
  53. package/dist/operations/work-orders-list.d.ts +81 -0
  54. package/dist/path.d.ts +13 -0
  55. package/dist/raw-request.d.ts +26 -0
  56. package/dist/request.d.ts +28 -0
  57. package/dist/result.d.ts +111 -43
  58. package/dist/retry.d.ts +34 -0
  59. package/dist/sensitivity.d.ts +89 -4
  60. package/dist/tolerant.d.ts +21 -0
  61. package/dist/validation.d.ts +3 -0
  62. package/package.json +6 -3
  63. package/dist/endpoint.d.ts +0 -66
  64. package/dist/endpoints/crm/address.d.ts +0 -20
  65. package/dist/endpoints/crm/create-contract.d.ts +0 -109
  66. package/dist/endpoints/crm/create-customer.d.ts +0 -65
  67. package/dist/endpoints/crm/update-customer-status.d.ts +0 -43
  68. package/dist/endpoints/os/list-occurrence-reasons.d.ts +0 -24
  69. package/dist/endpoints/os/list-occurrence-types.d.ts +0 -25
  70. package/dist/endpoints/precadastro/list-due-days.d.ts +0 -19
  71. package/dist/endpoints/precadastro/list-sellers.d.ts +0 -21
  72. package/dist/endpoints/suporte/add-customer-document.d.ts +0 -24
  73. package/dist/endpoints/suporte/list-customer-documents.d.ts +0 -25
  74. package/dist/endpoints/ura/check-coverage.d.ts +0 -46
  75. package/dist/endpoints/ura/list-annotations.d.ts +0 -32
  76. package/dist/endpoints/ura/list-clients.d.ts +0 -58
  77. package/dist/endpoints/ura/list-contracts.d.ts +0 -45
  78. package/dist/endpoints/ura/list-invoices.d.ts +0 -107
  79. package/dist/endpoints/ura/list-nas.d.ts +0 -29
  80. package/dist/endpoints/ura/list-occurrence-methods.d.ts +0 -19
  81. package/dist/endpoints/ura/list-payment-carriers.d.ts +0 -20
  82. package/dist/endpoints/ura/list-pops.d.ts +0 -19
  83. package/dist/endpoints/ura/list-service-orders.d.ts +0 -64
  84. package/dist/endpoints/ura/open-ticket.d.ts +0 -81
  85. package/dist/errors.d.ts +0 -59
  86. package/dist/schema/parse.d.ts +0 -19
  87. package/dist/schema/paths.d.ts +0 -38
  88. package/dist/transport.d.ts +0 -65
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ import type { OperationDefinition } from "../operation.js";
3
+ declare const preRegistrationPlansSchema: z.ZodArray<z.ZodObject<{
4
+ id: z.core.$ZodBranded<z.ZodNumber, "PreRegistrationPlanId", "out">;
5
+ tipo: z.ZodNullable<z.ZodOptional<z.ZodString>>;
6
+ valor: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
7
+ descricao: z.ZodNullable<z.ZodOptional<z.ZodString>>;
8
+ observacao: z.ZodNullable<z.ZodOptional<z.ZodString>>;
9
+ gateway: z.ZodNullable<z.ZodOptional<z.ZodObject<{
10
+ gateway_id: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
11
+ id: z.ZodNullable<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
12
+ descricao: z.ZodNullable<z.ZodOptional<z.ZodString>>;
13
+ }, z.core.$loose>>>;
14
+ }, z.core.$loose>>;
15
+ /**
16
+ * The response of `POST /api/precadastro/plano/list`, in SGP's own shape: a bare array with one
17
+ * entry per plan of the pré-cadastro catalog. The route is not paginated, so there is no envelope
18
+ * and no total. Each `id` is a `PreRegistrationPlanId`, a type apart from the `PlanId` of
19
+ * `plans.list`.
20
+ */
21
+ export type PreRegistrationsListPlansData = z.output<typeof preRegistrationPlansSchema>;
22
+ /** INTERNAL definition of `preRegistrations.listPlans`. */
23
+ export declare const preRegistrationsListPlans: OperationDefinition<PreRegistrationsListPlansData, "preRegistrations.listPlans">;
24
+ export {};
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ import type { OperationDefinition } from "../operation.js";
3
+ declare const sellersSchema: z.ZodArray<z.ZodObject<{
4
+ id: z.ZodNumber;
5
+ nome: z.ZodNullable<z.ZodOptional<z.ZodString>>;
6
+ cpf: z.ZodNullable<z.ZodOptional<z.ZodString>>;
7
+ email: z.ZodNullable<z.ZodOptional<z.ZodString>>;
8
+ }, z.core.$loose>>;
9
+ /**
10
+ * The response of `POST /api/precadastro/vendedor/list`, in SGP's own shape: a bare array with one
11
+ * entry per seller. The route is not paginated, so there is no envelope and no total.
12
+ */
13
+ export type PreRegistrationsListSellersData = z.output<typeof sellersSchema>;
14
+ /** INTERNAL definition of `preRegistrations.listSellers`. */
15
+ export declare const preRegistrationsListSellers: OperationDefinition<PreRegistrationsListSellersData, "preRegistrations.listSellers">;
16
+ export {};
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import type { OperationDefinition } from "../operation.js";
3
+ import type { PlanId } from "./plans-list.js";
4
+ /** Input of `services.addTv`, named as SGP names the fields. */
5
+ export interface ServiceAddTvInput {
6
+ /** Exercised. ID of the contract; it must be active (SGP refuses otherwise). */
7
+ clientecontrato_id: number;
8
+ /**
9
+ * Exercised. ID of the TV plan, a `PlanId` from the URA plan list (`plans.list`): a TV plan was
10
+ * accepted and a read-back confirmed the plan. The ID spaces differ: a plan id from this list
11
+ * was refused (400) as `plano_id` on the pré-cadastro route while accepted (200) as
12
+ * `planobase_id` here.
13
+ */
14
+ planobase_id: PlanId;
15
+ /** Exercised. Free-text note about the service. Personal data: never log it. */
16
+ info_extra?: string;
17
+ /** Documented, never sent. ID of the equipment type. */
18
+ tipo_equipamento?: number;
19
+ /**
20
+ * Documented, never sent. ID of the address to copy to the installation (omitted: the
21
+ * customer's).
22
+ */
23
+ endereco_id?: number;
24
+ }
25
+ /** INTERNAL. Validation of the input, exported so a test can check it against the public type. */
26
+ export declare const servicesAddTvInputSchema: z.ZodObject<{
27
+ clientecontrato_id: z.ZodNumber;
28
+ planobase_id: z.core.$ZodBranded<z.ZodNumber, "PlanId", "out">;
29
+ info_extra: z.ZodOptional<z.ZodString>;
30
+ tipo_equipamento: z.ZodOptional<z.ZodNumber>;
31
+ endereco_id: z.ZodOptional<z.ZodNumber>;
32
+ }, z.core.$strict>;
33
+ /**
34
+ * Success body of `POST /api/servico/tv` (HTTP 201): SGP's `msg`, the new `servico_id` (a number)
35
+ * and `clientecontrato_id`, which SGP sends as a string (`"<n>"`) and is kept as such. Other keys
36
+ * SGP may add are kept.
37
+ */
38
+ declare const tvAddedSchema: z.ZodObject<{
39
+ msg: z.ZodString;
40
+ clientecontrato_id: z.ZodOptional<z.ZodString>;
41
+ servico_id: z.ZodNumber;
42
+ }, z.core.$loose>;
43
+ /** Response of `services.addTv`. */
44
+ export type ServiceAddTvData = z.output<typeof tvAddedSchema>;
45
+ /** INTERNAL definition of `services.addTv`. */
46
+ export declare const servicesAddTv: OperationDefinition<ServiceAddTvData, "services.addTv">;
47
+ export {};
@@ -0,0 +1,40 @@
1
+ import { z } from "zod";
2
+ import type { OperationDefinition } from "../operation.js";
3
+ import type { PlanId } from "./plans-list.js";
4
+ /**
5
+ * Input of `services.changePlan`, named as SGP names the fields. `action` is fixed by the method
6
+ * (`change_plano`) and is not an input.
7
+ */
8
+ export interface ServiceChangePlanInput {
9
+ /** Exercised. ID of the serviço to change (the `id` of `customers.list` -> `servicos[]`). */
10
+ servico_id: number;
11
+ /**
12
+ * Exercised with `1` only (`SERVICE_TYPE.internet`). Type of the serviço; required. Any
13
+ * positive integer is sent and SGP decides what it takes, but only internet was ever exercised.
14
+ */
15
+ servico_tipo: number;
16
+ /**
17
+ * Exercised. ID of the new plan, a `PlanId` from the URA catalog (`plans.list`), which is the ID
18
+ * space of operations on existing services (not the pré-cadastro catalog of
19
+ * `preRegistrations.listPlans`, whose ids are `PreRegistrationPlanId`).
20
+ */
21
+ plano_id: PlanId;
22
+ }
23
+ /** INTERNAL. Validation of the input, exported so a test can check it against the public type. */
24
+ export declare const servicesChangePlanInputSchema: z.ZodObject<{
25
+ servico_id: z.ZodNumber;
26
+ servico_tipo: z.ZodNumber;
27
+ plano_id: z.core.$ZodBranded<z.ZodNumber, "PlanId", "out">;
28
+ }, z.core.$strict>;
29
+ /**
30
+ * Success body of `POST /api/suporte/service/update/{servico_id}/`: SGP's `msg`. It names neither
31
+ * the service nor the plan. Other keys SGP may add are kept.
32
+ */
33
+ declare const planChangedSchema: z.ZodObject<{
34
+ msg: z.ZodString;
35
+ }, z.core.$loose>;
36
+ /** Response of `services.changePlan`. */
37
+ export type ServiceChangePlanData = z.output<typeof planChangedSchema>;
38
+ /** INTERNAL definition of `services.changePlan`. */
39
+ export declare const servicesChangePlan: OperationDefinition<ServiceChangePlanData, "services.changePlan">;
40
+ export {};
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ import type { OperationDefinition } from "../operation.js";
3
+ /** Input of `services.removeTv`, named as SGP names the fields. */
4
+ export interface ServiceRemoveTvInput {
5
+ /** Exercised. ID of the TV serviço to remove (the `servico_id` of `services.addTv`). */
6
+ servico_id: number;
7
+ /** Exercised. ID of the contract the serviço belongs to. */
8
+ clientecontrato_id: number;
9
+ }
10
+ /** INTERNAL. Validation of the input, exported so a test can check it against the public type. */
11
+ export declare const servicesRemoveTvInputSchema: z.ZodObject<{
12
+ servico_id: z.ZodNumber;
13
+ clientecontrato_id: z.ZodNumber;
14
+ }, z.core.$strict>;
15
+ /**
16
+ * Success body of `DELETE /api/servico/tv/{servico_id}`: SGP's `msg`, the removed `servico_id` (a
17
+ * number) and `clientecontrato_id`, which SGP sends as a string and is kept as such. Other keys SGP
18
+ * may add are kept.
19
+ */
20
+ declare const tvRemovedSchema: z.ZodObject<{
21
+ msg: z.ZodString;
22
+ clientecontrato_id: z.ZodOptional<z.ZodString>;
23
+ servico_id: z.ZodNumber;
24
+ }, z.core.$loose>;
25
+ /** Response of `services.removeTv`. */
26
+ export type ServiceRemoveTvData = z.output<typeof tvRemovedSchema>;
27
+ /** INTERNAL definition of `services.removeTv`. */
28
+ export declare const servicesRemoveTv: OperationDefinition<ServiceRemoveTvData, "services.removeTv">;
29
+ export {};
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ import type { OperationDefinition } from "../operation.js";
3
+ declare const workOrderReasonsSchema: z.ZodArray<z.ZodObject<{
4
+ id: z.ZodNumber;
5
+ codigo: z.ZodNumber;
6
+ descricao: z.ZodNullable<z.ZodOptional<z.ZodString>>;
7
+ ativo: z.ZodNullable<z.ZodOptional<z.ZodBoolean>>;
8
+ classificacoes: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodUnknown>>>;
9
+ classificacoes_obrigatorio: z.ZodNullable<z.ZodOptional<z.ZodBoolean>>;
10
+ setores: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodUnknown>>>;
11
+ }, z.core.$loose>>;
12
+ /**
13
+ * The response of `GET /api/os/ocorrencia/motivo/list/`, in SGP's own shape: a bare array with one
14
+ * entry per occurrence reason (the `motivo` of a work order). The route is not paginated, so there
15
+ * is no envelope and no total.
16
+ */
17
+ export type WorkOrdersListReasonsData = z.output<typeof workOrderReasonsSchema>;
18
+ /** INTERNAL definition of `workOrders.listReasons`. */
19
+ export declare const workOrdersListReasons: OperationDefinition<WorkOrdersListReasonsData, "workOrders.listReasons">;
20
+ export {};
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ import type { OperationDefinition } from "../operation.js";
3
+ declare const pageSchema: z.ZodObject<{
4
+ paginacao: z.ZodObject<{
5
+ offset: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
6
+ limit: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
7
+ parcial: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
8
+ total: z.ZodNumber;
9
+ }, z.core.$loose>;
10
+ ordens_servicos: z.ZodArray<z.ZodObject<{
11
+ id: z.ZodNumber;
12
+ contrato: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
13
+ status_id: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
14
+ status: z.ZodNullable<z.ZodOptional<z.ZodString>>;
15
+ tipo_id: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
16
+ data_cadastro: z.ZodNullable<z.ZodOptional<z.ZodString>>;
17
+ cliente: z.ZodNullable<z.ZodOptional<z.ZodString>>;
18
+ contrato_status: z.ZodNullable<z.ZodOptional<z.ZodString>>;
19
+ contrato_status_id: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
20
+ ocorrencia: z.ZodNullable<z.ZodOptional<z.ZodString>>;
21
+ hora_cadastro: z.ZodNullable<z.ZodOptional<z.ZodString>>;
22
+ data_agendamento: z.ZodNullable<z.ZodOptional<z.ZodString>>;
23
+ hora_agendamento: z.ZodNullable<z.ZodOptional<z.ZodString>>;
24
+ data_finalizacao: z.ZodNullable<z.ZodOptional<z.ZodString>>;
25
+ hora_finalizacao: z.ZodNullable<z.ZodOptional<z.ZodString>>;
26
+ tipo: z.ZodNullable<z.ZodOptional<z.ZodString>>;
27
+ motivo: z.ZodNullable<z.ZodOptional<z.ZodString>>;
28
+ pop: z.ZodNullable<z.ZodOptional<z.ZodString>>;
29
+ conteudo: z.ZodNullable<z.ZodOptional<z.ZodString>>;
30
+ responsavel: z.ZodNullable<z.ZodOptional<z.ZodString>>;
31
+ tecnicos_auxiliares: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodUnknown>>>;
32
+ usuario: z.ZodNullable<z.ZodOptional<z.ZodString>>;
33
+ usuario_finalizacao: z.ZodNullable<z.ZodOptional<z.ZodString>>;
34
+ classificacoes: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodUnknown>>>;
35
+ }, z.core.$loose>>;
36
+ }, z.core.$loose>;
37
+ /**
38
+ * One page of `POST /api/ura/ordemservico/list/`, with SGP's own `paginacao`, returned as received:
39
+ *
40
+ * - `offset`: index of the first work order of the page (SGP starts at 0);
41
+ * - `limit`: page size SGP applied, which may differ from the one requested;
42
+ * - `parcial`: how many work orders this page holds (observed equal to `ordens_servicos.length`);
43
+ * - `total`: how many work orders match the filters in all, across every page.
44
+ *
45
+ * `total` is SGP's and never computed by the SDK: a page without a numeric `total` is
46
+ * `INVALID_RESPONSE`. Nothing here fetches the next page: ask for it with `offset`.
47
+ */
48
+ export type WorkOrdersListData = z.output<typeof pageSchema>;
49
+ /** Filters and paging of `workOrders.list`, named as SGP names them. All optional. */
50
+ export interface WorkOrdersListInput {
51
+ /** Index of the first work order of the page; SGP starts at 0. Non-negative integer. */
52
+ offset?: number;
53
+ /** Work orders per page. Non-negative integer; SGP decides the cap. */
54
+ limit?: number;
55
+ /**
56
+ * Work order id. SGP's collection describes it as the id of the occurrence (the OS); whether it
57
+ * matches `ordens_servicos[].id` or the `ocorrencia` number was not verified.
58
+ */
59
+ ordem_servico?: number;
60
+ /** Work order status id (`status_id` in the result; 0 is "Aberta" in the captures). */
61
+ status?: number;
62
+ /** POP id. */
63
+ pop?: number;
64
+ /** Occurrence reason id. */
65
+ motivo?: number;
66
+ /** Only work orders of this contract. */
67
+ contrato?: number;
68
+ }
69
+ /** INTERNAL. Validation of the input, exported so a test can check its keys are classified. */
70
+ export declare const workOrdersListInputSchema: z.ZodObject<{
71
+ offset: z.ZodOptional<z.ZodNumber>;
72
+ limit: z.ZodOptional<z.ZodNumber>;
73
+ ordem_servico: z.ZodOptional<z.ZodNumber>;
74
+ status: z.ZodOptional<z.ZodNumber>;
75
+ pop: z.ZodOptional<z.ZodNumber>;
76
+ motivo: z.ZodOptional<z.ZodNumber>;
77
+ contrato: z.ZodOptional<z.ZodNumber>;
78
+ }, z.core.$strict>;
79
+ /** INTERNAL definition of `workOrders.list`. */
80
+ export declare const workOrdersList: OperationDefinition<WorkOrdersListData, "workOrders.list">;
81
+ export {};
package/dist/path.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Fills the `{name}` placeholders of `template` with URL-encoded `pathParams`. Otherwise the first
3
+ * problem, named without its value: a placeholder with no value, an empty value, `.`/`..` (dot
4
+ * segments would change the route), a number that is not a safe integer, a value that cannot be
5
+ * encoded (lone surrogate), or a `pathParams` key that is not in the template.
6
+ */
7
+ export declare const resolvePath: (template: string, pathParams?: Readonly<Record<string, string | number>>) => {
8
+ ok: true;
9
+ path: string;
10
+ } | {
11
+ ok: false;
12
+ problem: string;
13
+ };
@@ -0,0 +1,26 @@
1
+ import type { CallOptions, ResolvedConfig } from "./config.js";
2
+ import type { Encoding } from "./operation.js";
3
+ import type { SgpResult } from "./result.js";
4
+ /** Input of `request()`. */
5
+ export interface RawRequestInput {
6
+ /** HTTP method. Which one a route needs is for the caller to know: the SDK never infers it. */
7
+ method: "GET" | "POST" | "PUT" | "DELETE";
8
+ /**
9
+ * Route on the configured SGP instance, e.g. `/api/ura/clientes/`: it starts with `/api/` and is
10
+ * already in its final form (no query, no fragment, no `//`, no `.`/`..` segments, no `%`).
11
+ * Anything else is refused locally with `INVALID_INPUT` before a request is sent. Put query
12
+ * parameters of a GET in `body`. `;` is sent literally (it stays on the same origin, under `/api/`).
13
+ */
14
+ path: string;
15
+ /**
16
+ * Request fields. A GET has no body: they go in the query string (primitives only). Other
17
+ * methods send them in `encoding`; a `json` body must be serializable (no `BigInt`, no cycle)
18
+ * and a `form` body takes primitives only. It is copied once when the call starts. Credentials are added by the SDK and cannot be
19
+ * overridden.
20
+ */
21
+ body?: Readonly<Record<string, unknown>>;
22
+ /** Body encoding of POST/PUT/DELETE: `json` (default) or `form` (multipart text fields). */
23
+ encoding?: Encoding;
24
+ }
25
+ /** INTERNAL. Runs `request()`: validates the destination, then the shared executor. */
26
+ export declare const executeRawRequest: (config: ResolvedConfig, input: RawRequestInput, options?: CallOptions) => Promise<SgpResult<unknown>>;
@@ -0,0 +1,28 @@
1
+ import type { ResolvedConfig } from "./config.js";
2
+ import type { OperationDefinition, RequestBuild } from "./operation.js";
3
+ /** What goes on the wire for one attempt. */
4
+ export interface EncodedRequest {
5
+ url: string;
6
+ headers?: Record<string, string>;
7
+ body?: string | FormData;
8
+ }
9
+ /** The parts of a successful `buildRequest` that the encoder writes: body fields, files, URL query. */
10
+ type BuiltRequest = Pick<Extract<RequestBuild, {
11
+ ok: true;
12
+ }>, "params" | "files" | "query">;
13
+ /**
14
+ * Encodes one request. A GET never has a body: params and credentials go in the query string
15
+ * (primitives only, `undefined` omitted). Every other method (POST, PUT and DELETE alike) sends
16
+ * the body in the operation's encoding: `json`, or `form` (multipart text fields, no content-type
17
+ * header so `fetch` adds the boundary), or `form-files`, the same plus one part per file (written
18
+ * before the credentials, so these stay last). Credentials are written once and last, so a param
19
+ * can never replace or repeat them. `undefined` when a GET or form param is not a primitive.
20
+ *
21
+ * `query` is for a request that has a body: its entries go in the URL after the path (primitives
22
+ * only, `undefined` omitted; none, or only `undefined`, leaves the URL as it was) while the
23
+ * credentials stay in the body. A GET already puts everything in the query string, so a GET with a
24
+ * `query`, a `query` that is not made of primitives, or one that names `token` or `app` gives
25
+ * `undefined`.
26
+ */
27
+ export declare const encodeRequest: (config: ResolvedConfig, definition: Pick<OperationDefinition<unknown>, "method" | "encoding">, path: string, built?: BuiltRequest) => EncodedRequest | undefined;
28
+ export {};
package/dist/result.d.ts CHANGED
@@ -1,55 +1,123 @@
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;
10
- /**
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.
15
- */
16
- detail?: string;
17
- /** Request path only, without query string. */
18
- endpoint: 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;
67
+ /** On `INVALID_RESPONSE`: the paths that broke the contract, never values. */
68
+ issues?: readonly string[];
69
+ }
70
+ /** A hook that threw. Only its name and the attempt it ran on are kept, never the thrown value. */
71
+ export interface Diagnostic {
72
+ /** Which hook threw. */
73
+ hook: "onRequest" | "onResponse" | "onError";
74
+ /** Attempt number (1-based) during which the hook ran. */
75
+ occurrence: number;
19
76
  }
20
- /** A non-key field whose type did not match the schema; reports type names, never values. */
77
+ /** Fields every result carries, on success and on failure. */
78
+ export interface ResultBase {
79
+ /** Requests the SDK started: 0 when refused locally, 1 for the first transport call. */
80
+ attempts: number;
81
+ /** Present only when a hook failed. */
82
+ diagnostics?: readonly Diagnostic[];
83
+ }
84
+ /**
85
+ * A field that did not have the type the method expects but is not essential to the response. The
86
+ * field left `data` and stays untouched in `response.body`, unless that body is `withheld` (then it
87
+ * is not recoverable). Type names only, never values.
88
+ */
21
89
  export interface SchemaWarning {
90
+ /** Where the mismatch is, with real indices: `clientes[0].contratos[1].status`. */
22
91
  path: string;
92
+ /**
93
+ * The field that is absent from `data` because of it. Equal to `path`, except when the mismatch is
94
+ * an array element: the whole array field is dropped (`clientes[0].contatos.emails`).
95
+ */
96
+ dropped: string;
97
+ /** Type the method expects (`string`, or `number | string` when several are accepted). */
23
98
  expected: string;
99
+ /** Type that arrived: `string`, `number`, `boolean`, `null`, `undefined`, `array` or `object`. */
24
100
  received: string;
25
101
  }
26
- /** Outcome of every SDK method; methods never throw for network, HTTP or schema failures. */
27
- export type SgpResult<T> = {
28
- success: true;
102
+ /** Successful call. `response` is the raw HTTP response the data came from. */
103
+ export interface SgpSuccess<T> extends ResultBase {
104
+ /** Discriminant: `true` on success. */
105
+ ok: true;
106
+ /** What the method returns, decoded from the response. */
29
107
  data: T;
30
- warnings?: SchemaWarning[];
31
- } | {
32
- success: false;
108
+ /** The HTTP response `data` came from. */
109
+ response: CapturedResponse;
110
+ /** Present only when a non-essential field was dropped from `data`; see {@link SchemaWarning}. */
111
+ warnings?: readonly SchemaWarning[];
112
+ }
113
+ /** Failed call. `response` is `null` when no HTTP response was available. */
114
+ export interface SgpFailure extends ResultBase {
115
+ /** Discriminant: `false` on failure. */
116
+ ok: false;
117
+ /** Why the call failed. */
33
118
  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
- };
119
+ /** The HTTP response received, or `null` when none was (refused locally, or the transport failed). */
120
+ response: CapturedResponse | null;
121
+ }
122
+ /** Outcome of every 2.0 method: expected failures are returned, never thrown. */
123
+ 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;