@lingara/api 0.0.0-reserved.0 → 0.1.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +117 -1
- package/dist/index.cjs +930 -0
- package/dist/index.d.cts +1000 -0
- package/dist/index.d.ts +1000 -0
- package/dist/index.mjs +907 -0
- package/package.json +55 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Spinning Cat Studios
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,119 @@
|
|
|
1
1
|
# @lingara/api
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The official TypeScript library for the [Lingara API](https://getlingara.com),
|
|
4
|
+
for **Node ≥ 22, Deno 2 and Bun 1**. It has **no runtime dependencies**:
|
|
5
|
+
every runtime it targets already ships `fetch`, `ReadableStream`,
|
|
6
|
+
`TextDecoder` and `AbortSignal`, so installing it installs nothing else.
|
|
7
|
+
|
|
8
|
+
## Not for the browser
|
|
9
|
+
|
|
10
|
+
This library is for your server. The Lingara API authenticates with a client
|
|
11
|
+
secret, and a secret shipped to a browser is published: anyone who opens the
|
|
12
|
+
page can read it and spend your allowance. The API sends no CORS headers for
|
|
13
|
+
third-party origins for the same reason. The
|
|
14
|
+
[authentication guide](https://getlingara.com/guides/authentication) explains
|
|
15
|
+
why credentials stay on a server.
|
|
16
|
+
|
|
17
|
+
So the `Lingara` constructor **refuses a `clientSecret` wherever a DOM
|
|
18
|
+
exists** (`globalThis.document` is defined), and there is no override. If
|
|
19
|
+
that fires in your own tests, run them in a `node` test environment rather
|
|
20
|
+
than `jsdom`. A client built without credentials, for the three public
|
|
21
|
+
operations, is not refused.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npm install @lingara/api
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Deno: `import { Lingara } from "npm:@lingara/api";`. Bun: `bun add @lingara/api`.
|
|
30
|
+
|
|
31
|
+
## Quick start
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { Lingara } from "@lingara/api";
|
|
35
|
+
|
|
36
|
+
const client = new Lingara({
|
|
37
|
+
clientId: process.env.LINGARA_CLIENT_ID!,
|
|
38
|
+
clientSecret: process.env.LINGARA_CLIENT_SECRET!,
|
|
39
|
+
// version: "2026-09-knowing-tenpounder", // optional pin
|
|
40
|
+
// onDeprecation: (notice) => metrics.warn(notice),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// A stream is an async iterable; the request starts on the first read.
|
|
44
|
+
const ac = new AbortController();
|
|
45
|
+
for await (const ev of client.generateVocabulary({ level: 2, source_lang: "en", target_lang: "zh", count: 8 }, { signal: ac.signal })) {
|
|
46
|
+
if (ev.event === "item") console.log(ev.data.word, ev.data.translation);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// A JSON call resolves with the body; `servedVersion` rides beside it.
|
|
50
|
+
const usage = await client.getUsage();
|
|
51
|
+
console.log(usage.servedVersion, usage.allowance);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Nine methods, each named after its `operationId`: `generateVocabulary`,
|
|
55
|
+
`createLessonPlan`, `streamLessonPlan` and `sendTutorMessage` return an
|
|
56
|
+
`EventStream`; `getLessonPlan`, `getUsage`, `getOpenApiDocument`,
|
|
57
|
+
`listApiVersions` and `getApiVersion` return a promise. The last three need
|
|
58
|
+
no credentials. Every method takes `{ signal?: AbortSignal }` last.
|
|
59
|
+
|
|
60
|
+
- `break` out of a `for await`, or `stream.close()`, closes the connection.
|
|
61
|
+
- A stream's `error` event is thrown as an `ApiError` with `status: 200`;
|
|
62
|
+
`done` ends iteration and is not yielded; `result` and `pending` are
|
|
63
|
+
yielded, then iteration ends.
|
|
64
|
+
- `await stream.servedVersion` gives the `Lingara-Version` echo, and never
|
|
65
|
+
rejects.
|
|
66
|
+
|
|
67
|
+
## Errors
|
|
68
|
+
|
|
69
|
+
Everything the library throws is a `LingaraError`: `ApiError` (a refusal from
|
|
70
|
+
`/v1`, or a stream's `error` event), `OAuthError` (the token endpoint),
|
|
71
|
+
`MaintenanceError` (a plain-text 503) or `TransportError` (no usable answer:
|
|
72
|
+
`kind` is `connect`, `tls`, `reset`, `timeout`, `stream_ended_early`,
|
|
73
|
+
`malformed_response` or `malformed_event`). Cancelling throws your signal's
|
|
74
|
+
own `reason`, never a `LingaraError`. `instanceof` works even when the ESM
|
|
75
|
+
and CommonJS builds are both loaded in one process.
|
|
76
|
+
|
|
77
|
+
The client secret and access tokens never appear in any rendering of the
|
|
78
|
+
client, its token source or an error; they show as `[REDACTED]`.
|
|
79
|
+
|
|
80
|
+
## Options
|
|
81
|
+
|
|
82
|
+
| Option | Default |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `clientId`, `clientSecret` | none: a credential-free client |
|
|
85
|
+
| `auth` | `"basic"` (`client_secret_basic`); `"post"` for `client_secret_post` |
|
|
86
|
+
| `scopes` | none: every scope the client is allowed |
|
|
87
|
+
| `tokenSource` | a `ClientCredentials` built from the options above; supply your own `TokenSource` instead of `clientSecret` |
|
|
88
|
+
| `baseUrl` / `tokenUrl` | `https://api.getlingara.com` / `…/oauth/token` |
|
|
89
|
+
| `version` | none: your client's pinned version |
|
|
90
|
+
| `onDeprecation` | one `console.warn` per deprecated version id |
|
|
91
|
+
| `maxAttempts` | `3`; `1` turns retries off |
|
|
92
|
+
| `retryAfterCapSeconds` | `60`: a longer `Retry-After` is thrown, with `retryAfter` set |
|
|
93
|
+
| `streamIdleTimeoutMs` | `120000`, counted only while a read is waiting |
|
|
94
|
+
| `tokenRequestTimeoutMs` | `30000` |
|
|
95
|
+
| `userAgentSuffix` | none: appended after the library's own token |
|
|
96
|
+
| `fetch` | `globalThis.fetch` |
|
|
97
|
+
| `clock`, `sleeper` | the real ones |
|
|
98
|
+
|
|
99
|
+
`clock` and `sleeper` are **testing seams**: they let a test control refresh
|
|
100
|
+
timing and `Retry-After` sleeps without waiting in real time. Leave them
|
|
101
|
+
alone in production.
|
|
102
|
+
|
|
103
|
+
**The `version` option and the generated-for version.** The library's types
|
|
104
|
+
were generated from one frozen API version, which the warning below names. Leave
|
|
105
|
+
`version` unset and your OAuth client's server-side pin decides what is
|
|
106
|
+
served; the library never sends a default. When a response is served from
|
|
107
|
+
another version, the library logs one `console.warn` per served id: the
|
|
108
|
+
response shapes may differ from the types. Pin the OAuth client (or set
|
|
109
|
+
`version`) to the generated-for version, or upgrade the library.
|
|
110
|
+
|
|
111
|
+
## The contract
|
|
112
|
+
|
|
113
|
+
This library keeps the contract every official Lingara library keeps, and
|
|
114
|
+
runs its conformance suite on Node 22 and 24, Deno 2 and Bun 1:
|
|
115
|
+
[`conformance/CONTRACT.md`](../conformance/CONTRACT.md).
|
|
116
|
+
|
|
117
|
+
## Licence
|
|
118
|
+
|
|
119
|
+
MIT.
|