@team-plain/graphql 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # @team-plain/graphql
2
+
3
+ A typed TypeScript SDK for [Plain's](https://plain.com) GraphQL API, auto-generated from the schema using a custom codegen pipeline.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @team-plain/graphql
9
+ ```
10
+
11
+ Requires **Node 25+**. ESM-only.
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { PlainClient } from "@team-plain/graphql";
17
+
18
+ const client = new PlainClient({ apiKey: "plainApiKey_xxx" });
19
+ ```
20
+
21
+ ### Query
22
+
23
+ ```ts
24
+ const customer = await client.customer({ customerId: "c_123" });
25
+ console.log(customer.fullName);
26
+
27
+ // Relations are lazy-loaded — accessing them makes a separate API call
28
+ const company = await customer.company;
29
+ console.log(company.name);
30
+ ```
31
+
32
+ ### Mutation
33
+
34
+ Mutation errors are returned as typed data, not thrown as exceptions. This matches Plain's API where all mutations return `*Output` types with an optional `error` field.
35
+
36
+ ```ts
37
+ const result = await client.upsertCustomer({
38
+ input: {
39
+ identifier: { emailAddress: "alice@example.com" },
40
+ onCreate: {
41
+ fullName: "Alice",
42
+ email: { email: "alice@example.com", isVerified: false },
43
+ },
44
+ onUpdate: {},
45
+ },
46
+ });
47
+
48
+ if (result.error) {
49
+ // Typed MutationError with message, type, code, and field-level errors
50
+ console.error(result.error.message);
51
+ result.error.fields?.forEach((f) => {
52
+ console.error(` ${f.field}: ${f.message}`);
53
+ });
54
+ } else {
55
+ console.log(result.customer?.id);
56
+ }
57
+ ```
58
+
59
+ ### Pagination
60
+
61
+ ```ts
62
+ const customers = await client.customers({ first: 10 });
63
+
64
+ for (const customer of customers.nodes) {
65
+ console.log(customer.fullName);
66
+ }
67
+
68
+ // Fetch the next page
69
+ const nextPage = await customers.fetchNext();
70
+ ```
71
+
72
+ ### Union Types
73
+
74
+ GraphQL union and interface fields are exposed as discriminated unions of model classes. Each union member has a `__typename` property for narrowing and supports the same lazy-loading as any other model.
75
+
76
+ ```ts
77
+ const thread = await client.thread({ threadId: "t_123" });
78
+
79
+ // Narrow with __typename
80
+ if (thread.createdBy.__typename === "UserActor") {
81
+ console.log(thread.createdBy.userId);
82
+
83
+ // Lazy-load a relation on the union member
84
+ const user = await thread.createdBy.user;
85
+ console.log(user?.fullName);
86
+ }
87
+
88
+ // Or narrow with instanceof
89
+ import { UserActorModel } from "@team-plain/graphql";
90
+
91
+ if (thread.createdBy instanceof UserActorModel) {
92
+ const user = await thread.createdBy.user;
93
+ }
94
+
95
+ // Value-like unions — scalars available immediately
96
+ if (thread.statusDetail?.__typename === "ThreadStatusDetailWaitingForDuration") {
97
+ console.log(thread.statusDetail.waitingUntil);
98
+ }
99
+
100
+ // List of unions
101
+ for (const identity of customer.identities) {
102
+ if (identity.__typename === "EmailCustomerIdentity") {
103
+ console.log(identity.email);
104
+ }
105
+ }
106
+ ```
107
+
108
+ ## Error Handling
109
+
110
+ - **Queries**: network, auth (401), forbidden (403), and rate limit (429) errors throw typed exceptions (`AuthenticationError`, `ForbiddenError`, `RateLimitError`, `NetworkError`, `PlainGraphQLError`).
111
+ - **Mutations**: return the full `*Output` type. Check `result.error` for a typed `MutationError` with `message`, `type`, `code`, and `fields[]`. This is intentional — Plain's API treats mutation errors as data.
112
+
113
+ ## Migrating from `@team-plain/typescript-sdk`
114
+
115
+ If you're migrating from the old `@team-plain/typescript-sdk` package, see the [Migration Guide](./MIGRATION.md) for a full breakdown of breaking changes including error handling, method renames, enum changes, and before/after examples.
116
+
117
+ ## Resources
118
+
119
+ - [Plain API docs](https://plain.com/docs) — guides, authentication, and API reference
120
+ - [GraphQL schema](https://core-api.uk.plain.com/graphql/v1/schema.graphql) — the full schema this SDK is generated from (also vendored at [`src/schema.graphql`](./src/schema.graphql))
121
+
122
+ ## License
123
+
124
+ [MIT](../../LICENSE)