@lemonadecms/client 0.0.0-stage → 0.1.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.
- package/CHANGELOG.md +84 -0
- package/LICENSE +21 -0
- package/README.md +304 -2
- package/bin/cli/config.mjs +309 -0
- package/bin/cli/create-migration.mjs +157 -0
- package/bin/cli/errors.mjs +9 -0
- package/bin/cli/io.mjs +70 -0
- package/bin/cli/migrate.mjs +109 -0
- package/bin/cli/network.mjs +134 -0
- package/bin/cli/picker.mjs +118 -0
- package/bin/cli/run.mjs +240 -0
- package/bin/cli/schema.mjs +397 -0
- package/bin/codegen/csharp.mjs +180 -0
- package/bin/codegen/definitions.mjs +52 -0
- package/bin/codegen/languages.mjs +16 -0
- package/bin/codegen/python.mjs +125 -0
- package/bin/generate-types.mjs +202 -0
- package/bin/lemonade.mjs +11 -0
- package/dist/errors.d.ts +24 -0
- package/dist/errors.js +39 -0
- package/dist/images.d.ts +11 -0
- package/dist/images.js +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +17 -0
- package/dist/preview.d.ts +11 -0
- package/dist/preview.js +92 -0
- package/dist/rich-text.d.ts +4 -0
- package/dist/rich-text.js +228 -0
- package/dist/server.browser.d.ts +2 -0
- package/dist/server.browser.js +9 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.js +17 -0
- package/dist/transport.d.ts +3 -0
- package/dist/transport.js +519 -0
- package/dist/types.d.ts +202 -0
- package/dist/types.js +6 -0
- package/package.json +52 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.1.1 — prepared release
|
|
6
|
+
|
|
7
|
+
- Add a native terminal environment picker for online `types generate` using
|
|
8
|
+
validated configured targets and their credential variables. Explicit settings,
|
|
9
|
+
CI, JSON/check/offline and piped runs stay noninteractive. Cancellation restores
|
|
10
|
+
the terminal and preserves files without network work. No dependencies added.
|
|
11
|
+
|
|
12
|
+
- Add bounded nested `and`/`or`/`not` filters, `ne`/`not_in`, literal text patterns
|
|
13
|
+
and case-insensitive matching. Existing arrays and scalar/choice operators stay
|
|
14
|
+
supported. Sort by 1–3 ordered fields with stable NULL/tie/backward pagination.
|
|
15
|
+
- Add typed paginated `search()` and reusable search options for reads, counts,
|
|
16
|
+
existence and lazy iteration. Uses the requested publication/locale snapshot
|
|
17
|
+
and PostgreSQL plain full-text relevance, with additive REST/RPC/GraphQL support.
|
|
18
|
+
Existing cursor forms and single-sort syntax remain compatible. No runtime,
|
|
19
|
+
optional or peer dependency was added; the updated CMS backend is required.
|
|
20
|
+
|
|
21
|
+
- `count()` and `exists()` query matching authorized snapshots directly without
|
|
22
|
+
downloading entries. `getMany()` reads at most 100 IDs in one request and
|
|
23
|
+
preserves order/duplicates with nullable missing entries. `findOneOrThrow()`
|
|
24
|
+
raises the exported `CMSNotFoundError` only for a successful empty match. All
|
|
25
|
+
support public/server-preview reads, typed options and existing cancellation,
|
|
26
|
+
deadline and error behavior; the updated CMS REST endpoints are required.
|
|
27
|
+
|
|
28
|
+
- `content(model).findOne()` returns the first typed matching entry or null using
|
|
29
|
+
one bounded query; preserves projections, metadata, filters, preview isolation
|
|
30
|
+
and existing error/cancellation/deadline behavior.
|
|
31
|
+
- `richTextToHtml()` and `richTextToPlainText()` render version-1 rich-text values
|
|
32
|
+
in browsers/servers with bounded traversal, escaped HTML, safe URLs and matching
|
|
33
|
+
expanded resources. Plain text excludes embeds and link URLs.
|
|
34
|
+
|
|
35
|
+
- Staff Admin manages release versions and notes in this Markdown file, with
|
|
36
|
+
exact-source preparation, durable activity and explicit npm publication through
|
|
37
|
+
a protected GitHub Actions job. Operator setup and live publishing qualification
|
|
38
|
+
remain separate; `--from-changelog` also selects this version locally.
|
|
39
|
+
|
|
40
|
+
- Repository maintainers can run `npm run release:sdk` to manage stable versions,
|
|
41
|
+
changelog notes, validation and exact archive preparation. `--publish` explicitly
|
|
42
|
+
enables npm upload and installed-registry verification; `--current` resumes the
|
|
43
|
+
selected version. The source package remains private.
|
|
44
|
+
|
|
45
|
+
- Entries include content-type identity, workspace/environment and locale beside
|
|
46
|
+
their existing ID, modeled fields and publication time. Optional TypeScript
|
|
47
|
+
metadata preserves existing entry fixtures; request identity supports older
|
|
48
|
+
CMS servers, while malformed/conflicting metadata is rejected safely.
|
|
49
|
+
- Expanded reference types describe additive raw REST context metadata. The
|
|
50
|
+
generated `Models` map still describes only custom fields, not entry envelopes.
|
|
51
|
+
|
|
52
|
+
- `lemonade types generate` loads the current project's `.env`, defaults to
|
|
53
|
+
`CMS_PROJECT_ID` / `CMS_PUBLIC_KEY`, Production and `src/types/cms-models.ts`.
|
|
54
|
+
Explicit flags, named targets and legacy `LEMONADE_*` settings still take
|
|
55
|
+
precedence; offline/management commands retain their credential boundaries.
|
|
56
|
+
C# and Python defaults use matching filenames in `src/types`.
|
|
57
|
+
|
|
58
|
+
- Keep CLI request deadlines bounded when Node 22's response-body transport
|
|
59
|
+
ignores native abort; best-effort stream cancellation cannot delay completion.
|
|
60
|
+
|
|
61
|
+
- Release preparation reads the selected version from package metadata, checks
|
|
62
|
+
package-lock/changelog agreement, and supports future stable/prerelease versions.
|
|
63
|
+
- Explicit public-registry verification checks archive integrity and isolated
|
|
64
|
+
npm/pnpm installations, runtime/types, both CLIs and browser-preview guards.
|
|
65
|
+
- Current installation documentation uses the published npm package. These
|
|
66
|
+
checkout changes do not replace the existing immutable registry artifact.
|
|
67
|
+
|
|
68
|
+
## 0.1.0 — published package
|
|
69
|
+
|
|
70
|
+
- Framework-independent ESM client and TypeScript declarations for published REST
|
|
71
|
+
collection/item reads, field selection, bounded pagination, filters, sorting,
|
|
72
|
+
localization, references and media helpers.
|
|
73
|
+
- Separate server-only draft-preview client with browser import/runtime guards.
|
|
74
|
+
- Schema-based model generation and the `lemonade` / `cms-codegen` commands.
|
|
75
|
+
- Fixed `https://lemonadecms.com` destination for customer reads; configure the
|
|
76
|
+
workspace ID and appropriately scoped credential. URL/host/environment overrides
|
|
77
|
+
fail before I/O. The credential selects the content environment.
|
|
78
|
+
- Optional request deadlines and cancellation. No automatic cache or retry policy.
|
|
79
|
+
- MIT license for this client package. This does not license the rest of the repository.
|
|
80
|
+
|
|
81
|
+
New applications import `@lemonadecms/client`. Existing local `@cms/client` imports
|
|
82
|
+
can use the documented file alias to a reviewed archive. Public availability of
|
|
83
|
+
0.1.0 is verified separately from publisher access, provenance and authorization
|
|
84
|
+
for a future release. Local preparation never publishes.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lemonade CMS contributors
|
|
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,305 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @lemonadecms/client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Framework-independent JavaScript and TypeScript SDK for reading Lemonade CMS
|
|
4
|
+
content. Published-content requests use REST. The package includes TypeScript
|
|
5
|
+
declarations, schema type generation and the `lemonade` developer CLI.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Install the published package in your application:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @lemonadecms/client
|
|
13
|
+
# or
|
|
14
|
+
pnpm add @lemonadecms/client
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Maintainers can test a future version using its reviewed candidate archive.
|
|
18
|
+
Check the supplied `SHA256SUMS`, then use the actual archive path:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
npm install --ignore-scripts /absolute/path/to/reviewed-client.tgz
|
|
22
|
+
# or
|
|
23
|
+
pnpm add /absolute/path/to/reviewed-client.tgz
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The package uses ESM and declares Node.js 22+. TypeScript consumers need
|
|
27
|
+
TypeScript 5+. Browser reads require standard `fetch`, `URL`, `URLSearchParams`
|
|
28
|
+
and `AbortController`; browser builds must use public credentials only. No
|
|
29
|
+
runtime library or framework dependency is required.
|
|
30
|
+
|
|
31
|
+
## Configure and read content
|
|
32
|
+
|
|
33
|
+
The SDK connects to `https://lemonadecms.com` automatically. Configure your
|
|
34
|
+
workspace and delivery key; there is no URL or local CMS option. Your website
|
|
35
|
+
can run locally while reading content from Lemonade production. Installing the
|
|
36
|
+
package does not create an account, workspace or delivery key.
|
|
37
|
+
|
|
38
|
+
Replace the workspace and key placeholders with values from your Lemonade workspace. Replace `content_item` and `title` with your content type and field
|
|
39
|
+
API identifiers, and publish an entry before fetching it.
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import { createCMSClient } from '@lemonadecms/client';
|
|
43
|
+
|
|
44
|
+
const cms = createCMSClient({
|
|
45
|
+
projectId: 'YOUR_WORKSPACE_UUID',
|
|
46
|
+
publicKey: 'YOUR_PUBLIC_DELIVERY_KEY',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const page = await cms.content('content_item').list({
|
|
50
|
+
select: ['title'],
|
|
51
|
+
limit: 10,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
for (const entry of page.data) {
|
|
55
|
+
console.log(entry.id, entry.fields.title);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const first = page.data[0];
|
|
59
|
+
if (first) {
|
|
60
|
+
const entry = await cms.content('content_item').get(first.id);
|
|
61
|
+
console.log(entry.fields, entry.publishedAt);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Entry values are under `fields`; metadata includes `id` and `publishedAt`.
|
|
66
|
+
Unreleased source builds also expose `contentType` (ID/key/name), `projectId`,
|
|
67
|
+
`environment` (ID/key) and resolved `locale`. Field projections retain metadata.
|
|
68
|
+
For older CMS responses, the SDK derives only the request's model key/workspace
|
|
69
|
+
and explicit locale; unavailable metadata stays absent. Metadata properties are
|
|
70
|
+
optional in TypeScript for compatibility with existing manually constructed
|
|
71
|
+
entries. Use `entry.contentType?.key`, not a custom `fields.contentType` field.
|
|
72
|
+
Generated `Models` describes fields; `ContentEntry<Models['content_item'],
|
|
73
|
+
'content_item'>` from the SDK describes the complete entry. Expanded reference
|
|
74
|
+
metadata remains raw snake_case. Published `0.1.0` does not include these additions.
|
|
75
|
+
An empty collection is `data: []`. Historical or selected fields can be missing
|
|
76
|
+
or `null`, so handle both when rendering. Continue a collection using
|
|
77
|
+
`page.meta.nextCursor` as the next request's `after` value while keeping the
|
|
78
|
+
other query options unchanged.
|
|
79
|
+
|
|
80
|
+
Use an existing `pk_` public delivery key or an `lmd_pk_` application token with
|
|
81
|
+
the required published-content grants. Anyone with that credential can read
|
|
82
|
+
the content it permits. Browser login cookies do not authorize SDK requests.
|
|
83
|
+
The credential selects the content environment; there is no separate SDK
|
|
84
|
+
environment override. Ask your Owner for a credential belonging to the intended
|
|
85
|
+
environment. The server rechecks current access, expiry and revocation on every
|
|
86
|
+
request.
|
|
87
|
+
|
|
88
|
+
## Find one entry
|
|
89
|
+
|
|
90
|
+
In the updated source build, `findOne()` returns the first matching complete
|
|
91
|
+
entry or `null`. It makes one request with `limit=1` and preserves existing
|
|
92
|
+
filters, search, sort, select, locale, includeRemote and signal options. It does not check
|
|
93
|
+
uniqueness. Pagination/limit options are rejected; HTTP/authorization, transport,
|
|
94
|
+
cancellation/deadline and malformed-response errors still reject. `get(id)` keeps
|
|
95
|
+
its existing UUID lookup and 404 behavior. Published `0.1.0` lacks these helpers.
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
const entry = await cms.content('content_item').findOne({
|
|
99
|
+
filters: [{ field: 'title', op: 'eq', value: 'Welcome' }],
|
|
100
|
+
select: ['title'],
|
|
101
|
+
});
|
|
102
|
+
console.log(entry?.fields.title ?? 'No matching content');
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Counts, existence and bulk reads
|
|
106
|
+
|
|
107
|
+
These unreleased methods require the updated SDK and CMS backend. They are
|
|
108
|
+
available in both published and server preview clients:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
import { CMSNotFoundError } from '@lemonadecms/client';
|
|
112
|
+
|
|
113
|
+
const content = cms.content('content_item');
|
|
114
|
+
const filters = [{ field: 'title', op: 'eq', value: 'Welcome' }];
|
|
115
|
+
const total = await content.count({ filters });
|
|
116
|
+
const available = await content.exists({ filters });
|
|
117
|
+
try {
|
|
118
|
+
const required = await content.findOneOrThrow({ filters, select: ['title'] });
|
|
119
|
+
const entries = await content.getMany([required.id], { select: ['title'] });
|
|
120
|
+
console.log(total, available, entries[0]?.fields.title);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (!(error instanceof CMSNotFoundError)) throw error;
|
|
123
|
+
console.log('Required content is unavailable');
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`count()`/`exists()` accept filters, search, locale and signal, using direct database
|
|
128
|
+
queries without downloading entries or expanding references. Count includes all
|
|
129
|
+
matches across pages; separate requests can see different publication states.
|
|
130
|
+
`getMany()` accepts up to 100 UUIDs and select/locale/includeRemote/signal. One
|
|
131
|
+
request returns entries in input order, preserving duplicate positions and using
|
|
132
|
+
`null` for missing/unpublished/foreign IDs in an otherwise authorized model.
|
|
133
|
+
Empty input returns `[]` without I/O after validation. Split larger ID sets into
|
|
134
|
+
batches; use the existing lazy `entries()`/`pages()` methods for collections.
|
|
135
|
+
`findOneOrThrow()` shares findOne options and throws `CMSNotFoundError` only for
|
|
136
|
+
a successful empty match. Authorization, HTTP, malformed-response, network,
|
|
137
|
+
cancellation and deadline failures retain their existing errors. Preview fields
|
|
138
|
+
may still be missing/null. No automatic collection-download fallback occurs.
|
|
139
|
+
|
|
140
|
+
## Advanced filters, search and sorting
|
|
141
|
+
|
|
142
|
+
Updated source builds support nested `and`/`or`/`not`, `ne`/`not_in`, and text
|
|
143
|
+
`eqi`, `contains`/`containsi`, `starts_with`/`starts_withi`, `ends_with`/`ends_withi`.
|
|
144
|
+
Existing filter arrays remain AND. Limits are ten leaves, 31 nodes, depth four
|
|
145
|
+
and 4 KiB; groups are nonempty. SQL wildcard characters are treated literally.
|
|
146
|
+
Positive comparisons on missing values are false; NOT and ne/not_in complement
|
|
147
|
+
them, including missing values. Use eq/ne null for explicit null checks.
|
|
148
|
+
|
|
149
|
+
```js
|
|
150
|
+
const matches = await cms.content('content_item').search('welcome', {
|
|
151
|
+
fields: ['title'],
|
|
152
|
+
select: ['title'],
|
|
153
|
+
filters: {
|
|
154
|
+
or: [
|
|
155
|
+
{ field: 'title', op: 'containsi', value: 'WELCOME' },
|
|
156
|
+
{ not: { field: 'title', op: 'eq', value: 'Archived' } },
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
sort: [
|
|
160
|
+
{ field: 'position', direction: 'desc' },
|
|
161
|
+
{ field: 'title', direction: 'asc' },
|
|
162
|
+
],
|
|
163
|
+
limit: 10,
|
|
164
|
+
});
|
|
165
|
+
console.log(matches.data);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`fields` scopes matching to 1–24 text/long_text/markdown fields; `select` projects
|
|
169
|
+
the returned fields. Omit fields to search all top-level fields of those types.
|
|
170
|
+
Query accepts 1–200 Unicode codepoints, up to 512 UTF-8 bytes and 16 whitespace
|
|
171
|
+
terms. PostgreSQL simple-config plain search requires every parsed term, with
|
|
172
|
+
cover-density relevance order by default. Explicit 1–3 unique sort fields override
|
|
173
|
+
relevance; NULLs stay last and UUID breaks ties. No stemming, fuzzy/prefix/phrase
|
|
174
|
+
search or recursive rich-text/reference search is implied. Matching and ranking
|
|
175
|
+
use only the authorized locale/fallback and published/preview snapshot.
|
|
176
|
+
|
|
177
|
+
`search()` makes one normal paginated collection request. Pass the same
|
|
178
|
+
`search: {query, fields}` object to list/findOne/findOneOrThrow/count/exists/pages/
|
|
179
|
+
entries to count or traverse matches. Keep the full query and ordered sort fields
|
|
180
|
+
unchanged when following cursors. Existing single-sort syntax remains supported.
|
|
181
|
+
Signed cursors have an 8 KiB limit. Unusually large Unicode text anchors that
|
|
182
|
+
exceed it after compression return `invalid_query`; choose more compact scalar
|
|
183
|
+
sort fields in that case.
|
|
184
|
+
These methods require the updated SDK/backend. Runtime/peer/optional dependencies
|
|
185
|
+
remain empty; no external search service is used.
|
|
186
|
+
|
|
187
|
+
## Rich-text helpers
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
import { richTextToHtml, richTextToPlainText } from '@lemonadecms/client';
|
|
191
|
+
|
|
192
|
+
// Replace rich_body with a rich_text field from your schema.
|
|
193
|
+
const richEntry = await cms.content('content_item').findOne({ select: ['rich_body'] });
|
|
194
|
+
const html = richTextToHtml(richEntry?.fields.rich_body);
|
|
195
|
+
const plainText = richTextToPlainText(richEntry?.fields.rich_body);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Both accept nullable/unknown version-1 rich-text JSON and work in browsers or
|
|
199
|
+
servers without a framework or DOM. HTML escapes text/attributes and renders only
|
|
200
|
+
supported nodes/marks, safe links and matching expanded image/entry-caption
|
|
201
|
+
resources. Unavailable embeds are omitted; entry routes are never invented.
|
|
202
|
+
Plain text retains authored text with block/list/hard-break newlines, omitting
|
|
203
|
+
embeds and link URLs. Plain text is not escaped HTML: use text interpolation.
|
|
204
|
+
|
|
205
|
+
Traversal is bounded to 500 nodes, depth 8, 200 children per node, 20 embeds,
|
|
206
|
+
20,000 UTF-8 bytes per text and 64 KiB of rendered source strings. Unsupported
|
|
207
|
+
versions, invalid roots/containers or exhausted budgets return empty strings;
|
|
208
|
+
unsupported parts are omitted. No raw HTML, resource-field recursion, I/O or
|
|
209
|
+
automatic Markdown conversion is performed. HTML URL/alt bounds and exact
|
|
210
|
+
preview-image conventions are documented in the SDK guide. The helpers are also
|
|
211
|
+
exported from the server entry; preview authorization remains your responsibility.
|
|
212
|
+
|
|
213
|
+
## Types, queries and framework examples
|
|
214
|
+
|
|
215
|
+
The [SDK guide](https://lemonadecms.com/guides/sdk) covers generated `Models`,
|
|
216
|
+
field selection, filtering, sorting, localization, cursor and numbered
|
|
217
|
+
pagination, errors, cancellation, images, and JavaScript/React/Vue/Nuxt examples.
|
|
218
|
+
Generate types from your own authorized schema and regenerate them after model
|
|
219
|
+
changes. Types help at compile time; they do not authenticate a request or
|
|
220
|
+
validate every field at runtime.
|
|
221
|
+
|
|
222
|
+
There is no automatic caching or retry policy. Your application owns rendering,
|
|
223
|
+
loading and error states, cache invalidation and safe HTML handling. Pass an
|
|
224
|
+
`AbortSignal` to cancel a read. Optional `timeoutMs` sets a per-request deadline;
|
|
225
|
+
combining a timeout with a caller signal requires `AbortSignal.any`.
|
|
226
|
+
|
|
227
|
+
## Choose an environment for generated types
|
|
228
|
+
|
|
229
|
+
The updated source CLI offers an interactive picker from configured targets:
|
|
230
|
+
|
|
231
|
+
```sh
|
|
232
|
+
npx lemonade types generate
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Create `lemonade.config.json` in your application. Replace both workspace
|
|
236
|
+
placeholders with your workspace UUID; the target labels distinguish environments.
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"version": 1,
|
|
241
|
+
"targets": {
|
|
242
|
+
"production": {
|
|
243
|
+
"url": "https://lemonadecms.com",
|
|
244
|
+
"workspace": "YOUR_WORKSPACE_UUID",
|
|
245
|
+
"environment": "production",
|
|
246
|
+
"credentialEnv": "CMS_PUBLIC_KEY"
|
|
247
|
+
},
|
|
248
|
+
"dev": {
|
|
249
|
+
"url": "https://lemonadecms.com",
|
|
250
|
+
"workspace": "YOUR_WORKSPACE_UUID",
|
|
251
|
+
"environment": "dev",
|
|
252
|
+
"credentialEnv": "CMS_DEV_PUBLIC_KEY"
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Keep actual credentials in your current directory's `.env` or process environment;
|
|
259
|
+
process values win. A dev target needs a dev-scoped credential. The credential
|
|
260
|
+
selects access; the CLI verifies the returned workspace/environment before writing.
|
|
261
|
+
The picker lists configured targets, not environments discovered from the CMS.
|
|
262
|
+
|
|
263
|
+
Use arrows and Enter. Production is initially selected when configured; otherwise
|
|
264
|
+
the first target alphabetically. Escape/Ctrl+C/EOF exits 130 without network or
|
|
265
|
+
output-file writes. Terminal input mode is restored on success, cancellation/error.
|
|
266
|
+
Missing/revoked/mismatched credentials fail without replacing existing types.
|
|
267
|
+
|
|
268
|
+
Explicit `--target`, `--environment`, `--url`, `--workspace` or `--credential-env`
|
|
269
|
+
bypasses the picker, as do `LEMONADE_TARGET`, `LEMONADE_ENVIRONMENT` or
|
|
270
|
+
`CMS_ENVIRONMENT`. CI, `--json`, `--check`, piped input/output, `--file` and other
|
|
271
|
+
commands never prompt. `--config` can choose the target configuration file.
|
|
272
|
+
Without configured targets, existing defaults remain unchanged. For automation:
|
|
273
|
+
|
|
274
|
+
```sh
|
|
275
|
+
npx lemonade types generate --target dev --check
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
This requires the updated source package; published 0.1.0 lacks the picker.
|
|
279
|
+
It uses native Node APIs and retains zero runtime, peer or optional dependencies.
|
|
280
|
+
|
|
281
|
+
## Private previews
|
|
282
|
+
|
|
283
|
+
For draft reads, use `createCMSPreviewClient` from
|
|
284
|
+
`@lemonadecms/client/server` in trusted server code with a server-only
|
|
285
|
+
`secretKey`. Authenticate and authorize the requesting user in your application
|
|
286
|
+
before fetching or returning drafts. Do not create an anonymous preview proxy.
|
|
287
|
+
Never put preview credentials or private responses in browser bundles, public
|
|
288
|
+
environment variables, shared caches, static output or logs. The server export
|
|
289
|
+
rejects browser use; that guard does not replace your application's authorization.
|
|
290
|
+
|
|
291
|
+
`@lemonadecms/client/preview` is a separate optional click-to-edit helper for an
|
|
292
|
+
already authorized website preview. It provides no preview credential or draft
|
|
293
|
+
fetch client.
|
|
294
|
+
|
|
295
|
+
## Guides
|
|
296
|
+
|
|
297
|
+
- [Getting started](https://lemonadecms.com/guides)
|
|
298
|
+
- [SDK reference and examples](https://lemonadecms.com/guides/sdk)
|
|
299
|
+
- [Troubleshooting](https://lemonadecms.com/guides/troubleshooting)
|
|
300
|
+
- [Repository](https://github.com/ilara-booqself/lemonadecms)
|
|
301
|
+
|
|
302
|
+
## License
|
|
303
|
+
|
|
304
|
+
This SDK package is licensed under the [MIT License](LICENSE). Its license does
|
|
305
|
+
not grant a license to the entire CMS repository or the separate native clients.
|