@relyio/sdk 0.2.1 → 0.4.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/CHANGELOG.md +116 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/{chunk-RJBIJ2ZK.js → chunk-43VPZT2G.js} +496 -103
- package/dist/chunk-BBUB7C2Z.js +81 -0
- package/dist/{chunk-FJK7ZWKK.cjs → chunk-HAQELDZN.cjs} +156 -221
- package/dist/chunk-LSRPMNPT.cjs +89 -0
- package/dist/{chunk-7W4MJXQ4.cjs → chunk-XS32U2UP.cjs} +497 -102
- package/dist/{chunk-2QUK2ZGD.js → chunk-XY5KFEFY.js} +157 -219
- package/dist/client/index.cjs +4 -3
- package/dist/client/index.d.cts +4 -3
- package/dist/client/index.d.ts +4 -3
- package/dist/client/index.js +2 -1
- package/dist/define-content-type-CBfnTWSS.d.cts +716 -0
- package/dist/define-content-type-CBfnTWSS.d.ts +716 -0
- package/dist/{define-schema-DHvUCKwj.d.cts → define-schema-2xbHgtK-.d.cts} +63 -726
- package/dist/{define-schema-DHvUCKwj.d.ts → define-schema-DzYXk4HL.d.ts} +63 -726
- package/dist/dev-handshake/index.cjs +37 -0
- package/dist/dev-handshake/index.d.cts +144 -0
- package/dist/dev-handshake/index.d.ts +144 -0
- package/dist/dev-handshake/index.js +4 -0
- package/dist/{index-DGWaawHt.d.cts → index-BvO6HDtY.d.cts} +237 -12
- package/dist/{index-B-KiFHbx.d.ts → index-BzOFJJKS.d.ts} +237 -12
- package/dist/{index-BsUqCAu8.d.cts → index-DFehx5sI.d.cts} +749 -2160
- package/dist/{index-BsUqCAu8.d.ts → index-FDak5ofk.d.ts} +749 -2160
- package/dist/index.cjs +120 -70
- package/dist/index.d.cts +136 -55
- package/dist/index.d.ts +136 -55
- package/dist/index.js +45 -3
- package/dist/schema/index.cjs +35 -47
- package/dist/schema/index.d.cts +3 -2
- package/dist/schema/index.d.ts +3 -2
- package/dist/schema/index.js +1 -1
- package/dist/types/index.d.cts +2 -1
- package/dist/types/index.d.ts +2 -1
- package/package.json +15 -19
- package/dist/react/index.cjs +0 -4
- package/dist/react/index.d.cts +0 -2
- package/dist/react/index.d.ts +0 -2
- package/dist/react/index.js +0 -3
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkLSRPMNPT_cjs = require('../chunk-LSRPMNPT.cjs');
|
|
4
|
+
require('../chunk-MWMSFIWN.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "DEV_CONTEXT_DIR", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkLSRPMNPT_cjs.DEV_CONTEXT_DIR; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "DEV_CONTEXT_FILE", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunkLSRPMNPT_cjs.DEV_CONTEXT_FILE; }
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "DEV_CONTEXT_FILENAME", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return chunkLSRPMNPT_cjs.DEV_CONTEXT_FILENAME; }
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(exports, "DEV_ENV", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return chunkLSRPMNPT_cjs.DEV_ENV; }
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "buildDevEnv", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () { return chunkLSRPMNPT_cjs.buildDevEnv; }
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(exports, "parseDevContextFile", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function () { return chunkLSRPMNPT_cjs.parseDevContextFile; }
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports, "parseDevEnv", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function () { return chunkLSRPMNPT_cjs.parseDevEnv; }
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=index.cjs.map
|
|
37
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `relyio dev` handshake: the one declaration of how a sandbox reaches a running app.
|
|
3
|
+
*
|
|
4
|
+
* `relyio dev` provisions an ephemeral sandbox and hands its connection details to the developer's
|
|
5
|
+
* app by two carriers, which `sandboxes-spec.md` presents as interchangeable:
|
|
6
|
+
*
|
|
7
|
+
* 1. **Env** — `relyio dev -- pnpm dev` injects `RELYIO_DEV_*` into the wrapped child process.
|
|
8
|
+
* 2. **File** — `.relyio/dev.json`, for an app started standalone beside the cockpit.
|
|
9
|
+
*
|
|
10
|
+
* Three consumers read this: the SDK (both carriers), and `relyio promote` (the file, to work out
|
|
11
|
+
* which sandbox this repo is developing against). Before REL-647 each had its own copy of the
|
|
12
|
+
* answer and the three disagreed — the file required `branchId` in the CLI and not in the SDK, an
|
|
13
|
+
* unparseable deadline read as *unbounded*, and **the env carrier had no expiry at all**, so
|
|
14
|
+
* `relyio dev` and `relyio dev -- pnpm dev` were not in fact interchangeable: the same lapsed
|
|
15
|
+
* sandbox stopped working under one and kept working for the life of the process under the other.
|
|
16
|
+
*
|
|
17
|
+
* So this module is the declaration, and it is deliberately **pure** — no `node:*`, no I/O, no
|
|
18
|
+
* clock of its own. Each consumer keeps the I/O shell it needs (the SDK cannot statically import
|
|
19
|
+
* `node:fs`; the CLI is async and knows the project root) and none of them keeps a rule.
|
|
20
|
+
*
|
|
21
|
+
* **On the direction of the dependency.** The CLI *writes* this file and the SDK *reads* it, so
|
|
22
|
+
* publishing the declaration from the reader inverts writer→reader, which is worth knowing when
|
|
23
|
+
* you change it. It is the right trade anyway: the SDK is already dependency-free and browser-safe
|
|
24
|
+
* by construction, so the declaration costs it nothing, while the CLI bundles every `@relyio/*`
|
|
25
|
+
* into its published artifact and can absorb the import. The alternative — a third package — buys
|
|
26
|
+
* a version stream for four constants and a parser.
|
|
27
|
+
*/
|
|
28
|
+
/** Directory, relative to the project root, that holds the dev artifact. Hidden, git-ignored. */
|
|
29
|
+
declare const DEV_CONTEXT_DIR = ".relyio";
|
|
30
|
+
/** Filename of the dev artifact inside {@link DEV_CONTEXT_DIR}. */
|
|
31
|
+
declare const DEV_CONTEXT_FILENAME = "dev.json";
|
|
32
|
+
/**
|
|
33
|
+
* Path of the dev artifact relative to the project root, POSIX-separated.
|
|
34
|
+
*
|
|
35
|
+
* The one place this path is spelled. It is also exactly the `.gitignore` entry, which must use a
|
|
36
|
+
* forward slash on every platform — so the constant is a literal rather than a `path.join`, and
|
|
37
|
+
* callers that need a filesystem path join it onto their own root.
|
|
38
|
+
*/
|
|
39
|
+
declare const DEV_CONTEXT_FILE = ".relyio/dev.json";
|
|
40
|
+
/**
|
|
41
|
+
* The environment variables `relyio dev` injects into a wrapped child process.
|
|
42
|
+
*
|
|
43
|
+
* `expiresAt` is the REL-647 addition. Without it the env carrier could not express a deadline, so
|
|
44
|
+
* it was exempt from the expiry the file carrier enforced — which is the whole of Gap 3.
|
|
45
|
+
*/
|
|
46
|
+
declare const DEV_ENV: {
|
|
47
|
+
readonly dataset: "RELYIO_DEV_DATASET";
|
|
48
|
+
readonly apiKey: "RELYIO_DEV_API_KEY";
|
|
49
|
+
readonly expiresAt: "RELYIO_DEV_EXPIRES_AT";
|
|
50
|
+
};
|
|
51
|
+
/** The `.relyio/dev.json` shape, as `relyio dev` writes it. All four keys; `expiresAt` nullable. */
|
|
52
|
+
interface DevContext {
|
|
53
|
+
/** Ephemeral sandbox dataset the app should read (`X-RelyIO-Dataset`). */
|
|
54
|
+
datasetId: string;
|
|
55
|
+
/** Scoped read-only preview key for the sandbox dataset (`X-API-Key`). */
|
|
56
|
+
previewApiKey: string;
|
|
57
|
+
/** Sandbox branch id — informational to the SDK; `relyio promote` identifies the sandbox by it. */
|
|
58
|
+
branchId: string;
|
|
59
|
+
/**
|
|
60
|
+
* ISO deadline of the sandbox's current lifecycle state, or null when unbounded.
|
|
61
|
+
*
|
|
62
|
+
* This is `sandbox.expiresAt` from the provisioning bundle — when the sandbox is due to be
|
|
63
|
+
* suspended or archived — not the preview key's own `expiresAt`. Past it, the dataset may be
|
|
64
|
+
* archived and the key deactivated, so the handshake names a sandbox that no longer answers.
|
|
65
|
+
*/
|
|
66
|
+
expiresAt: string | null;
|
|
67
|
+
}
|
|
68
|
+
/** The credentials a carrier yields once it has been accepted. */
|
|
69
|
+
interface DevCredentials {
|
|
70
|
+
dataset: string;
|
|
71
|
+
apiKey: string;
|
|
72
|
+
}
|
|
73
|
+
/** Why a carrier's payload could not be understood. */
|
|
74
|
+
type DevUnreadableReason = 'not-json' | 'missing-fields' | 'bad-expiry';
|
|
75
|
+
/**
|
|
76
|
+
* What a carrier says, as a closed set of named states.
|
|
77
|
+
*
|
|
78
|
+
* There is deliberately no `null` or falsy arm, on any path. "Expired", "absent" and "corrupt" lead
|
|
79
|
+
* to different advice — refresh the key, start a sandbox, delete the file — and collapsing them to
|
|
80
|
+
* one falsy value is what let an app with a lapsed sandbox read **production** in silence and let
|
|
81
|
+
* `relyio promote` act on a stale identity. An absent input is a declared state, not a default.
|
|
82
|
+
*/
|
|
83
|
+
type DevContextVerdict = {
|
|
84
|
+
state: 'active';
|
|
85
|
+
context: DevContext;
|
|
86
|
+
} | {
|
|
87
|
+
state: 'expired';
|
|
88
|
+
context: DevContext;
|
|
89
|
+
expiredAt: string;
|
|
90
|
+
} | {
|
|
91
|
+
state: 'unreadable';
|
|
92
|
+
reason: DevUnreadableReason;
|
|
93
|
+
} | {
|
|
94
|
+
state: 'absent';
|
|
95
|
+
};
|
|
96
|
+
/** What the env carrier says. It carries no `branchId`; only the file identifies a branch. */
|
|
97
|
+
type DevEnvVerdict = {
|
|
98
|
+
state: 'active';
|
|
99
|
+
credentials: DevCredentials;
|
|
100
|
+
expiresAt: string | null;
|
|
101
|
+
} | {
|
|
102
|
+
state: 'expired';
|
|
103
|
+
expiredAt: string;
|
|
104
|
+
} | {
|
|
105
|
+
state: 'unreadable';
|
|
106
|
+
reason: DevUnreadableReason;
|
|
107
|
+
} | {
|
|
108
|
+
state: 'absent';
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Decide what the text of `.relyio/dev.json` says, against a caller-supplied clock.
|
|
112
|
+
*
|
|
113
|
+
* All three of `datasetId`, `previewApiKey` and `branchId` are **required**. `relyio dev` has
|
|
114
|
+
* always written all four keys and the spec documents all four, so a file missing one is corrupt
|
|
115
|
+
* rather than a narrower dialect — before REL-647 the CLI required `branchId` and the SDK did not,
|
|
116
|
+
* so one file read as absent to one binary and usable to the other.
|
|
117
|
+
*
|
|
118
|
+
* The clock is a parameter rather than a `Date.now()` inside, so the boundary is testable without
|
|
119
|
+
* faking time, and so this module stays pure.
|
|
120
|
+
*/
|
|
121
|
+
declare function parseDevContextFile(raw: string, now: number): DevContextVerdict;
|
|
122
|
+
/**
|
|
123
|
+
* Build the `RELYIO_DEV_*` environment `relyio dev` injects into a wrapped child.
|
|
124
|
+
*
|
|
125
|
+
* The counterpart of {@link parseDevEnv}, and the reason the env names are single-sourced: the
|
|
126
|
+
* binary that writes them and the library that reads them now use one object. `expiresAt` is
|
|
127
|
+
* omitted rather than emitted empty when the sandbox is unbounded, so the variable's presence
|
|
128
|
+
* means "there is a deadline".
|
|
129
|
+
*/
|
|
130
|
+
declare function buildDevEnv(context: Pick<DevContext, 'datasetId' | 'previewApiKey' | 'expiresAt'>): Record<string, string>;
|
|
131
|
+
/**
|
|
132
|
+
* Decide what the `RELYIO_DEV_*` environment says, against a caller-supplied clock.
|
|
133
|
+
*
|
|
134
|
+
* The env carrier names no branch, so it yields credentials rather than a {@link DevContext}. It
|
|
135
|
+
* applies the same deadline rule the file does — that equivalence is Gap 3, and the reason
|
|
136
|
+
* {@link DEV_ENV}`.expiresAt` exists at all.
|
|
137
|
+
*
|
|
138
|
+
* A deadline present but unreadable refuses the credentials. That is deliberate and is the same
|
|
139
|
+
* choice the file path makes: a wrapped process whose deadline we cannot read is not a process we
|
|
140
|
+
* can say is inside its window.
|
|
141
|
+
*/
|
|
142
|
+
declare function parseDevEnv(env: Record<string, string | undefined> | undefined, now: number): DevEnvVerdict;
|
|
143
|
+
|
|
144
|
+
export { DEV_CONTEXT_DIR, DEV_CONTEXT_FILE, DEV_CONTEXT_FILENAME, DEV_ENV, type DevContext, type DevContextVerdict, type DevCredentials, type DevEnvVerdict, type DevUnreadableReason, buildDevEnv, parseDevContextFile, parseDevEnv };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `relyio dev` handshake: the one declaration of how a sandbox reaches a running app.
|
|
3
|
+
*
|
|
4
|
+
* `relyio dev` provisions an ephemeral sandbox and hands its connection details to the developer's
|
|
5
|
+
* app by two carriers, which `sandboxes-spec.md` presents as interchangeable:
|
|
6
|
+
*
|
|
7
|
+
* 1. **Env** — `relyio dev -- pnpm dev` injects `RELYIO_DEV_*` into the wrapped child process.
|
|
8
|
+
* 2. **File** — `.relyio/dev.json`, for an app started standalone beside the cockpit.
|
|
9
|
+
*
|
|
10
|
+
* Three consumers read this: the SDK (both carriers), and `relyio promote` (the file, to work out
|
|
11
|
+
* which sandbox this repo is developing against). Before REL-647 each had its own copy of the
|
|
12
|
+
* answer and the three disagreed — the file required `branchId` in the CLI and not in the SDK, an
|
|
13
|
+
* unparseable deadline read as *unbounded*, and **the env carrier had no expiry at all**, so
|
|
14
|
+
* `relyio dev` and `relyio dev -- pnpm dev` were not in fact interchangeable: the same lapsed
|
|
15
|
+
* sandbox stopped working under one and kept working for the life of the process under the other.
|
|
16
|
+
*
|
|
17
|
+
* So this module is the declaration, and it is deliberately **pure** — no `node:*`, no I/O, no
|
|
18
|
+
* clock of its own. Each consumer keeps the I/O shell it needs (the SDK cannot statically import
|
|
19
|
+
* `node:fs`; the CLI is async and knows the project root) and none of them keeps a rule.
|
|
20
|
+
*
|
|
21
|
+
* **On the direction of the dependency.** The CLI *writes* this file and the SDK *reads* it, so
|
|
22
|
+
* publishing the declaration from the reader inverts writer→reader, which is worth knowing when
|
|
23
|
+
* you change it. It is the right trade anyway: the SDK is already dependency-free and browser-safe
|
|
24
|
+
* by construction, so the declaration costs it nothing, while the CLI bundles every `@relyio/*`
|
|
25
|
+
* into its published artifact and can absorb the import. The alternative — a third package — buys
|
|
26
|
+
* a version stream for four constants and a parser.
|
|
27
|
+
*/
|
|
28
|
+
/** Directory, relative to the project root, that holds the dev artifact. Hidden, git-ignored. */
|
|
29
|
+
declare const DEV_CONTEXT_DIR = ".relyio";
|
|
30
|
+
/** Filename of the dev artifact inside {@link DEV_CONTEXT_DIR}. */
|
|
31
|
+
declare const DEV_CONTEXT_FILENAME = "dev.json";
|
|
32
|
+
/**
|
|
33
|
+
* Path of the dev artifact relative to the project root, POSIX-separated.
|
|
34
|
+
*
|
|
35
|
+
* The one place this path is spelled. It is also exactly the `.gitignore` entry, which must use a
|
|
36
|
+
* forward slash on every platform — so the constant is a literal rather than a `path.join`, and
|
|
37
|
+
* callers that need a filesystem path join it onto their own root.
|
|
38
|
+
*/
|
|
39
|
+
declare const DEV_CONTEXT_FILE = ".relyio/dev.json";
|
|
40
|
+
/**
|
|
41
|
+
* The environment variables `relyio dev` injects into a wrapped child process.
|
|
42
|
+
*
|
|
43
|
+
* `expiresAt` is the REL-647 addition. Without it the env carrier could not express a deadline, so
|
|
44
|
+
* it was exempt from the expiry the file carrier enforced — which is the whole of Gap 3.
|
|
45
|
+
*/
|
|
46
|
+
declare const DEV_ENV: {
|
|
47
|
+
readonly dataset: "RELYIO_DEV_DATASET";
|
|
48
|
+
readonly apiKey: "RELYIO_DEV_API_KEY";
|
|
49
|
+
readonly expiresAt: "RELYIO_DEV_EXPIRES_AT";
|
|
50
|
+
};
|
|
51
|
+
/** The `.relyio/dev.json` shape, as `relyio dev` writes it. All four keys; `expiresAt` nullable. */
|
|
52
|
+
interface DevContext {
|
|
53
|
+
/** Ephemeral sandbox dataset the app should read (`X-RelyIO-Dataset`). */
|
|
54
|
+
datasetId: string;
|
|
55
|
+
/** Scoped read-only preview key for the sandbox dataset (`X-API-Key`). */
|
|
56
|
+
previewApiKey: string;
|
|
57
|
+
/** Sandbox branch id — informational to the SDK; `relyio promote` identifies the sandbox by it. */
|
|
58
|
+
branchId: string;
|
|
59
|
+
/**
|
|
60
|
+
* ISO deadline of the sandbox's current lifecycle state, or null when unbounded.
|
|
61
|
+
*
|
|
62
|
+
* This is `sandbox.expiresAt` from the provisioning bundle — when the sandbox is due to be
|
|
63
|
+
* suspended or archived — not the preview key's own `expiresAt`. Past it, the dataset may be
|
|
64
|
+
* archived and the key deactivated, so the handshake names a sandbox that no longer answers.
|
|
65
|
+
*/
|
|
66
|
+
expiresAt: string | null;
|
|
67
|
+
}
|
|
68
|
+
/** The credentials a carrier yields once it has been accepted. */
|
|
69
|
+
interface DevCredentials {
|
|
70
|
+
dataset: string;
|
|
71
|
+
apiKey: string;
|
|
72
|
+
}
|
|
73
|
+
/** Why a carrier's payload could not be understood. */
|
|
74
|
+
type DevUnreadableReason = 'not-json' | 'missing-fields' | 'bad-expiry';
|
|
75
|
+
/**
|
|
76
|
+
* What a carrier says, as a closed set of named states.
|
|
77
|
+
*
|
|
78
|
+
* There is deliberately no `null` or falsy arm, on any path. "Expired", "absent" and "corrupt" lead
|
|
79
|
+
* to different advice — refresh the key, start a sandbox, delete the file — and collapsing them to
|
|
80
|
+
* one falsy value is what let an app with a lapsed sandbox read **production** in silence and let
|
|
81
|
+
* `relyio promote` act on a stale identity. An absent input is a declared state, not a default.
|
|
82
|
+
*/
|
|
83
|
+
type DevContextVerdict = {
|
|
84
|
+
state: 'active';
|
|
85
|
+
context: DevContext;
|
|
86
|
+
} | {
|
|
87
|
+
state: 'expired';
|
|
88
|
+
context: DevContext;
|
|
89
|
+
expiredAt: string;
|
|
90
|
+
} | {
|
|
91
|
+
state: 'unreadable';
|
|
92
|
+
reason: DevUnreadableReason;
|
|
93
|
+
} | {
|
|
94
|
+
state: 'absent';
|
|
95
|
+
};
|
|
96
|
+
/** What the env carrier says. It carries no `branchId`; only the file identifies a branch. */
|
|
97
|
+
type DevEnvVerdict = {
|
|
98
|
+
state: 'active';
|
|
99
|
+
credentials: DevCredentials;
|
|
100
|
+
expiresAt: string | null;
|
|
101
|
+
} | {
|
|
102
|
+
state: 'expired';
|
|
103
|
+
expiredAt: string;
|
|
104
|
+
} | {
|
|
105
|
+
state: 'unreadable';
|
|
106
|
+
reason: DevUnreadableReason;
|
|
107
|
+
} | {
|
|
108
|
+
state: 'absent';
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Decide what the text of `.relyio/dev.json` says, against a caller-supplied clock.
|
|
112
|
+
*
|
|
113
|
+
* All three of `datasetId`, `previewApiKey` and `branchId` are **required**. `relyio dev` has
|
|
114
|
+
* always written all four keys and the spec documents all four, so a file missing one is corrupt
|
|
115
|
+
* rather than a narrower dialect — before REL-647 the CLI required `branchId` and the SDK did not,
|
|
116
|
+
* so one file read as absent to one binary and usable to the other.
|
|
117
|
+
*
|
|
118
|
+
* The clock is a parameter rather than a `Date.now()` inside, so the boundary is testable without
|
|
119
|
+
* faking time, and so this module stays pure.
|
|
120
|
+
*/
|
|
121
|
+
declare function parseDevContextFile(raw: string, now: number): DevContextVerdict;
|
|
122
|
+
/**
|
|
123
|
+
* Build the `RELYIO_DEV_*` environment `relyio dev` injects into a wrapped child.
|
|
124
|
+
*
|
|
125
|
+
* The counterpart of {@link parseDevEnv}, and the reason the env names are single-sourced: the
|
|
126
|
+
* binary that writes them and the library that reads them now use one object. `expiresAt` is
|
|
127
|
+
* omitted rather than emitted empty when the sandbox is unbounded, so the variable's presence
|
|
128
|
+
* means "there is a deadline".
|
|
129
|
+
*/
|
|
130
|
+
declare function buildDevEnv(context: Pick<DevContext, 'datasetId' | 'previewApiKey' | 'expiresAt'>): Record<string, string>;
|
|
131
|
+
/**
|
|
132
|
+
* Decide what the `RELYIO_DEV_*` environment says, against a caller-supplied clock.
|
|
133
|
+
*
|
|
134
|
+
* The env carrier names no branch, so it yields credentials rather than a {@link DevContext}. It
|
|
135
|
+
* applies the same deadline rule the file does — that equivalence is Gap 3, and the reason
|
|
136
|
+
* {@link DEV_ENV}`.expiresAt` exists at all.
|
|
137
|
+
*
|
|
138
|
+
* A deadline present but unreadable refuses the credentials. That is deliberate and is the same
|
|
139
|
+
* choice the file path makes: a wrapped process whose deadline we cannot read is not a process we
|
|
140
|
+
* can say is inside its window.
|
|
141
|
+
*/
|
|
142
|
+
declare function parseDevEnv(env: Record<string, string | undefined> | undefined, now: number): DevEnvVerdict;
|
|
143
|
+
|
|
144
|
+
export { DEV_CONTEXT_DIR, DEV_CONTEXT_FILE, DEV_CONTEXT_FILENAME, DEV_ENV, type DevContext, type DevContextVerdict, type DevCredentials, type DevEnvVerdict, type DevUnreadableReason, buildDevEnv, parseDevContextFile, parseDevEnv };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { J as MergedRelyIOConfig, A as ApiPath, a as ApiMethod, K as PathParamsOf, t as ApiResponse, W as Wire, s as RequestConfig, B as BaseContent, d as WhereClause, f as SortOptions, g as ContentQueryResult, Q as QueryOptions, C as CreateInput, U as UpdateInput, S as SDKError, x as BaseValidationError, w as ValidationViolation, N as components, O as paths, R as RelyIOConfig } from './index-DFehx5sI.cjs';
|
|
2
|
+
import { a as SchemaDefinition, b as SchemaContentTypeNames, h as SchemaAssetTypeNames, M as InferAssetType, c as SchemaSingletonNames, t as InferSingleton, g as SchemaSettingsGroupNames, E as InferSettingsGroup, e as SchemaQueryNames, f as SchemaLocaleCodes } from './define-schema-2xbHgtK-.cjs';
|
|
3
|
+
import { J as InferContentType } from './define-content-type-CBfnTWSS.cjs';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* What a call site supplies beside the route it named.
|
|
@@ -38,7 +39,7 @@ declare class HttpClient {
|
|
|
38
39
|
private baseUrl;
|
|
39
40
|
private defaultHeaders;
|
|
40
41
|
private timeout;
|
|
41
|
-
private
|
|
42
|
+
private retryPolicy;
|
|
42
43
|
private debug;
|
|
43
44
|
private logger?;
|
|
44
45
|
private config;
|
|
@@ -56,7 +57,16 @@ declare class HttpClient {
|
|
|
56
57
|
data: unknown;
|
|
57
58
|
} ? Wire<P, M, T>['data'] : never>;
|
|
58
59
|
/**
|
|
59
|
-
* Make an HTTP request
|
|
60
|
+
* Make an HTTP request, retrying only where a retry is safe.
|
|
61
|
+
*
|
|
62
|
+
* The headers are merged **once**, before the first attempt, and every attempt
|
|
63
|
+
* sends that same object. That is what makes a minted `Idempotency-Key` stable
|
|
64
|
+
* across the retries of one logical write: the service sees one key and
|
|
65
|
+
* answers the replay from the original outcome instead of applying it twice.
|
|
66
|
+
*
|
|
67
|
+
* The loop always makes one attempt. The incumbent's `while (attempt <
|
|
68
|
+
* maxAttempts)` made none at `retryAttempts: 0` — a value the config validator
|
|
69
|
+
* accepts — and then dereferenced an unassigned `lastError`.
|
|
60
70
|
*/
|
|
61
71
|
request<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>>;
|
|
62
72
|
/**
|
|
@@ -99,6 +109,16 @@ declare class HttpClient {
|
|
|
99
109
|
* Get current base URL
|
|
100
110
|
*/
|
|
101
111
|
getBaseUrl(): string;
|
|
112
|
+
/**
|
|
113
|
+
* One attempt.
|
|
114
|
+
*
|
|
115
|
+
* The caller's `signal` and the timeout both end it, through one controller.
|
|
116
|
+
* The incumbent handed `fetch` the caller's signal **instead of** its own, so a
|
|
117
|
+
* request that passed a signal had no timeout at all — and a caller abort then
|
|
118
|
+
* surfaced as `Request timed out`. `timedOut` is what tells the two apart: a
|
|
119
|
+
* timeout is a `TimeoutError`, a caller abort is the platform's `AbortError`,
|
|
120
|
+
* rethrown as it came.
|
|
121
|
+
*/
|
|
102
122
|
private makeRequest;
|
|
103
123
|
/**
|
|
104
124
|
* Filter headers that browsers don't allow to be set manually
|
|
@@ -113,7 +133,7 @@ declare class HttpClient {
|
|
|
113
133
|
private mergeRequestConfig;
|
|
114
134
|
private buildQueryString;
|
|
115
135
|
private headersToObject;
|
|
116
|
-
|
|
136
|
+
/** A backoff the caller's abort cuts short; the next attempt then refuses to send. */
|
|
117
137
|
private sleep;
|
|
118
138
|
private log;
|
|
119
139
|
}
|
|
@@ -427,13 +447,20 @@ declare class ContentByIdBuilder<T extends BaseContent = BaseContent> {
|
|
|
427
447
|
*/
|
|
428
448
|
interface RetryableWriteOptions {
|
|
429
449
|
/**
|
|
430
|
-
* A
|
|
450
|
+
* A key that makes a retry of **this** write safe.
|
|
431
451
|
*
|
|
432
452
|
* A replay inside the service's window returns the original outcome rather
|
|
433
453
|
* than applying twice. The service derives that response from committed state
|
|
434
454
|
* pinned to the recorded version — it does not store bytes — so a replay after
|
|
435
455
|
* the version has been pruned is refused `RESOURCE_EXPIRED` rather than
|
|
436
456
|
* answered from a stale copy.
|
|
457
|
+
*
|
|
458
|
+
* **The SDK mints one when you do not.** It used to be caller-supplied and
|
|
459
|
+
* nothing else, which meant the default write carried no key while the retry
|
|
460
|
+
* loop replayed it anyway — the one mechanism that makes a replay safe was
|
|
461
|
+
* optional on the one path that needed it. Supply your own to make a key
|
|
462
|
+
* outlive the process: a job that may be restarted wants a key derived from
|
|
463
|
+
* the work, not one minted per call.
|
|
437
464
|
*/
|
|
438
465
|
idempotencyKey?: string;
|
|
439
466
|
}
|
|
@@ -2370,11 +2397,166 @@ declare class AdhocQueryClient {
|
|
|
2370
2397
|
}
|
|
2371
2398
|
|
|
2372
2399
|
/**
|
|
2373
|
-
*
|
|
2374
|
-
*
|
|
2375
|
-
*
|
|
2400
|
+
* Content and resource errors.
|
|
2401
|
+
*
|
|
2402
|
+
* `ContentTypeNotFoundError` and `ContentNotFoundError` were deleted at API5.
|
|
2403
|
+
* The mapper reached them by sniffing `CONTENT_TYPE_NOT_FOUND` and
|
|
2404
|
+
* `CONTENT_NOT_FOUND`, neither of which is in the closed vocabulary, so neither
|
|
2405
|
+
* class was reachable. Both cases are `RESOURCE_NOT_FOUND`, whose declared
|
|
2406
|
+
* `details` are `{ kind, id? }` — the same two facts, from the one code a route
|
|
2407
|
+
* can actually declare.
|
|
2408
|
+
*/
|
|
2409
|
+
declare class ResourceNotFoundError extends SDKError {
|
|
2410
|
+
readonly code = "RESOURCE_NOT_FOUND";
|
|
2411
|
+
readonly retryable = false;
|
|
2412
|
+
constructor(message?: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
|
|
2413
|
+
getUserMessage(): string;
|
|
2414
|
+
}
|
|
2415
|
+
declare class ResourceConflictError extends SDKError {
|
|
2416
|
+
readonly code = "RESOURCE_CONFLICT";
|
|
2417
|
+
readonly retryable = false;
|
|
2418
|
+
constructor(message?: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
|
|
2419
|
+
getUserMessage(): string;
|
|
2420
|
+
}
|
|
2421
|
+
declare class ResourceExpiredError extends SDKError {
|
|
2422
|
+
readonly code = "RESOURCE_EXPIRED";
|
|
2423
|
+
readonly retryable = false;
|
|
2424
|
+
constructor(message?: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
|
|
2425
|
+
getUserMessage(): string;
|
|
2426
|
+
}
|
|
2427
|
+
/**
|
|
2428
|
+
* "Did the service say this resource does not exist?"
|
|
2429
|
+
*
|
|
2430
|
+
* Reads the **code**, not the status. Four contract codes are 4xx on a read and
|
|
2431
|
+
* only one of them means "not there"; the incumbent checked `statusCode === 404`
|
|
2432
|
+
* on the thrown value, and a second arm duck-typed a plain object for the same
|
|
2433
|
+
* number so a hand-written test double would pass. Both are the branch
|
|
2434
|
+
* `INV-API-CLIENT-IS-DERIVED` forbids where a code exists — and the second one
|
|
2435
|
+
* only existed because the tests faked the boundary (rule 20). They now stub
|
|
2436
|
+
* `fetch`, so the double is gone with the branch.
|
|
2437
|
+
*/
|
|
2438
|
+
declare function isResourceNotFound(error: unknown): boolean;
|
|
2439
|
+
|
|
2440
|
+
/**
|
|
2441
|
+
* `relyio.changes()` — the changes feed as a typed long-poll iterator
|
|
2442
|
+
* (`sdk-surfaces-spec.md` decisions 16–18).
|
|
2443
|
+
*
|
|
2444
|
+
* Long-poll only, on purpose. `GET /v1/changes` is an ordinary cursor-paged
|
|
2445
|
+
* collection the committed document declares, so each poll is one `send` over
|
|
2446
|
+
* the one HTTP client (`INV-SS-ONE-CORE`, `INV-API-CLIENT-IS-DERIVED`). The SSE
|
|
2447
|
+
* branch the route also serves would be a second transport path inside that
|
|
2448
|
+
* client, and `parseResponse` buffers a whole body; it stays for `EventSource`
|
|
2449
|
+
* and curl consumers.
|
|
2450
|
+
*/
|
|
2451
|
+
|
|
2452
|
+
type PollChanges = paths['/v1/changes']['get'];
|
|
2453
|
+
/**
|
|
2454
|
+
* The 200 body the document declares, read from its `application/json` content
|
|
2455
|
+
* **by name**. The route also negotiates `text/event-stream`; naming the JSON
|
|
2456
|
+
* content is what keeps that alternate from changing this type when the
|
|
2457
|
+
* document gains it.
|
|
2458
|
+
*/
|
|
2459
|
+
type ChangesPageBody = PollChanges['responses'][200]['content']['application/json'];
|
|
2460
|
+
/**
|
|
2461
|
+
* One change, as the committed document describes an item of the feed's `data`
|
|
2462
|
+
* (`INV-SS-CHANGE-IS-IDS`: ids, content type, locale, kind and cursor — never a
|
|
2463
|
+
* document).
|
|
2464
|
+
*
|
|
2465
|
+
* Read from the document, never written here: the api's route row names the
|
|
2466
|
+
* `Change` component schema, and a change to it reaches this type when the
|
|
2467
|
+
* document is regenerated. `changes.types.ts` holds it equal to the document's
|
|
2468
|
+
* item, and fails if it is ever `unknown` again.
|
|
2469
|
+
*/
|
|
2470
|
+
type Change = ChangesPageBody['data'][number];
|
|
2471
|
+
/** Why a cursor could no longer be replayed. `unknown` when the message named neither. */
|
|
2472
|
+
type ChangesExpiredReason = 'retention' | 'dataset-replaced' | 'unknown';
|
|
2473
|
+
/**
|
|
2474
|
+
* `RESOURCE_EXPIRED` from the changes feed: the cursor names a position the
|
|
2475
|
+
* ledger can no longer replay from (`INV-SS-CURSOR-REPLAYS`). The consumer
|
|
2476
|
+
* resyncs from the read path and starts again without a cursor.
|
|
2477
|
+
*
|
|
2478
|
+
* A `ResourceExpiredError`, so code that already catches that still does. The
|
|
2479
|
+
* refusal declares no details, so `reason` is read from the message the api
|
|
2480
|
+
* writes (`apps/services/api/src/changes/changes-request.ts` `refusalOf`).
|
|
2481
|
+
*/
|
|
2482
|
+
declare class ChangesExpiredError extends ResourceExpiredError {
|
|
2483
|
+
readonly reason: ChangesExpiredReason;
|
|
2484
|
+
/** The base class's signature, so `withContext` can rebuild one. */
|
|
2485
|
+
constructor(message: string, statusCode?: number, cause?: Error, context?: Record<string, unknown>);
|
|
2486
|
+
static of(expired: ResourceExpiredError): ChangesExpiredError;
|
|
2487
|
+
}
|
|
2488
|
+
interface ChangesOptions {
|
|
2489
|
+
/**
|
|
2490
|
+
* A `page.nextCursor` — or a change's `cursor` — from an earlier poll. Omitted,
|
|
2491
|
+
* the first poll answers the dataset's current position and no changes, at
|
|
2492
|
+
* once, and the feed starts from there.
|
|
2493
|
+
*/
|
|
2494
|
+
since?: string;
|
|
2495
|
+
/** Content types to keep. Omitted keeps every type; an empty list is refused (400). */
|
|
2496
|
+
types?: readonly string[];
|
|
2497
|
+
/**
|
|
2498
|
+
* Entry ids to keep. Omitted keeps every entry. The api refuses more than it
|
|
2499
|
+
* allows (100 today) as `REQUEST_INVALID`, thrown from the iterator as an
|
|
2500
|
+
* `InvalidPayloadError` on the first poll; the SDK does not restate the
|
|
2501
|
+
* cap, so it cannot drift from the service's.
|
|
2502
|
+
*/
|
|
2503
|
+
ids?: readonly string[];
|
|
2504
|
+
/** Ledger rows one poll scans, 1 to 500; the api defaults to 100. */
|
|
2505
|
+
limit?: number;
|
|
2506
|
+
/**
|
|
2507
|
+
* Ends the iteration. An abort — in flight, between polls, or while waiting
|
|
2508
|
+
* out a `Retry-After` — makes the `for await` **complete**, with no further
|
|
2509
|
+
* request and no `AbortError` thrown into the loop.
|
|
2510
|
+
*/
|
|
2511
|
+
signal?: AbortSignal;
|
|
2512
|
+
/**
|
|
2513
|
+
* What to do when the cursor has expired.
|
|
2514
|
+
*
|
|
2515
|
+
* - `'throw'` (default) — the iterator throws {@link ChangesExpiredError}.
|
|
2516
|
+
* - `'resync'` — restart from the dataset's current position and keep going.
|
|
2517
|
+
* - a function — resync, and call it with the error once the new position is
|
|
2518
|
+
* taken and before any change after it is yielded. This is the observable
|
|
2519
|
+
* form: whatever the consumer derived from the feed may be stale, so the
|
|
2520
|
+
* function is where it invalidates everything. The iterator waits for it.
|
|
2521
|
+
*/
|
|
2522
|
+
onExpired?: 'throw' | 'resync' | ((expired: ChangesExpiredError) => void | Promise<void>);
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
/**
|
|
2526
|
+
* Any schema the client can be typed by. `any` is deliberate: the client accepts whatever content
|
|
2527
|
+
* types, components, singletons, queries and settings groups a customer declares.
|
|
2528
|
+
*
|
|
2529
|
+
* This is the constraint `TypedRelyIOClient`'s `TSchema` carries, so `RegisteredSchema` is inferred
|
|
2530
|
+
* against the same one — `createClient` returns `TypedRelyIOClient<RegisteredSchema>`, and a schema
|
|
2531
|
+
* inferred against any wider alias would not be provably inside the client's bound.
|
|
2376
2532
|
*/
|
|
2377
2533
|
type AnySchemaDefinition = SchemaDefinition<any, any, any, any, any>;
|
|
2534
|
+
/**
|
|
2535
|
+
* The seam `relyio generate-types` fills (`INV-SS-TYPES-INFERRED`).
|
|
2536
|
+
*
|
|
2537
|
+
* Empty here on purpose. The generated `schema.ts` augments it —
|
|
2538
|
+
*
|
|
2539
|
+
* ```ts
|
|
2540
|
+
* declare module '@relyio/sdk' {
|
|
2541
|
+
* interface Register {
|
|
2542
|
+
* schema: typeof schema
|
|
2543
|
+
* }
|
|
2544
|
+
* }
|
|
2545
|
+
* ```
|
|
2546
|
+
*
|
|
2547
|
+
* — and from then on `createClient({ apiKey })`, with no generic and no `schema:`, is typed by that
|
|
2548
|
+
* schema. The pattern is TanStack Router's. It is type-level only: nothing at runtime reads it.
|
|
2549
|
+
*/
|
|
2550
|
+
interface Register {
|
|
2551
|
+
}
|
|
2552
|
+
/**
|
|
2553
|
+
* The schema the project registered through `Register`, or `undefined` when nothing did — which is
|
|
2554
|
+
* the untyped client, exactly as before the generator ran.
|
|
2555
|
+
*/
|
|
2556
|
+
type RegisteredSchema = Register extends {
|
|
2557
|
+
schema: infer S extends AnySchemaDefinition;
|
|
2558
|
+
} ? S : undefined;
|
|
2559
|
+
|
|
2378
2560
|
/**
|
|
2379
2561
|
* Client configuration with optional schema
|
|
2380
2562
|
*/
|
|
@@ -2539,6 +2721,32 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
2539
2721
|
* ```
|
|
2540
2722
|
*/
|
|
2541
2723
|
batch(): BatchBuilder<NonNullable<TSchema>>;
|
|
2724
|
+
/**
|
|
2725
|
+
* Follow the dataset's changes feed: each write this key can see, as ids, in
|
|
2726
|
+
* order, long-polled from `GET /v1/changes`.
|
|
2727
|
+
*
|
|
2728
|
+
* Lazy — nothing is requested until the first `next()`. It runs until
|
|
2729
|
+
* `signal` aborts, which ends the `for await` cleanly rather than throwing.
|
|
2730
|
+
* A change names what changed; refetch it through the ordinary read path
|
|
2731
|
+
* (`INV-SS-CHANGE-IS-IDS`).
|
|
2732
|
+
*
|
|
2733
|
+
* @example
|
|
2734
|
+
* ```typescript
|
|
2735
|
+
* const controller = new AbortController()
|
|
2736
|
+
* for await (const change of relyio.changes({ since: cursor, types: ['post'], signal: controller.signal })) {
|
|
2737
|
+
* // { entryId, contentType, locale, kind, cursor }
|
|
2738
|
+
* }
|
|
2739
|
+
* ```
|
|
2740
|
+
*
|
|
2741
|
+
* @example Resync when the cursor has expired
|
|
2742
|
+
* ```typescript
|
|
2743
|
+
* for await (const change of relyio.changes({
|
|
2744
|
+
* since: cursor,
|
|
2745
|
+
* onExpired: async () => invalidateEverything(),
|
|
2746
|
+
* })) { … }
|
|
2747
|
+
* ```
|
|
2748
|
+
*/
|
|
2749
|
+
changes(options?: ChangesOptions): AsyncIterable<Change>;
|
|
2542
2750
|
/**
|
|
2543
2751
|
* Build and execute an ad-hoc query dynamically
|
|
2544
2752
|
*
|
|
@@ -2697,12 +2905,29 @@ declare class TypedRelyIOClient<TSchema extends AnySchemaDefinition | undefined
|
|
|
2697
2905
|
* // Content type names autocomplete!
|
|
2698
2906
|
* const products = await relyio.content('product').fetchAll()
|
|
2699
2907
|
* ```
|
|
2700
|
-
|
|
2908
|
+
*
|
|
2909
|
+
* @example After `relyio generate-types` (inferred, `INV-SS-TYPES-INFERRED`)
|
|
2910
|
+
* ```typescript
|
|
2911
|
+
* import { createClient } from '@relyio/sdk'
|
|
2912
|
+
*
|
|
2913
|
+
* // The generated `schema.ts` augments `Register`, so no generic and no `schema:` are needed
|
|
2914
|
+
* const relyio = createClient({ apiKey: process.env.RELYIO_API_KEY! })
|
|
2915
|
+
* ```
|
|
2916
|
+
*
|
|
2917
|
+
* The overload without a schema comes first on purpose. Behind the generic one it was never
|
|
2918
|
+
* chosen: with no `schema` to infer from, `TSchema` fell back to its constraint and the call
|
|
2919
|
+
* resolved to `TypedRelyIOClient<AnySchemaDefinition>`. First, it takes every call that passes no
|
|
2920
|
+
* schema, and returns the registered schema's client — or the untyped one when nothing registered.
|
|
2921
|
+
* A `schema:` value fails its `schema?: undefined`, and an explicit generic skips it because it has
|
|
2922
|
+
* no type parameter, so both reach the generic overload unchanged.
|
|
2923
|
+
*/
|
|
2924
|
+
declare function createClient(config: RelyIOConfig & {
|
|
2925
|
+
schema?: undefined;
|
|
2926
|
+
}): TypedRelyIOClient<RegisteredSchema>;
|
|
2701
2927
|
declare function createClient<TSchema extends AnySchemaDefinition>(config: TypedClientConfig<TSchema>): TypedRelyIOClient<TSchema>;
|
|
2702
|
-
declare function createClient(config: RelyIOConfig): TypedRelyIOClient<undefined>;
|
|
2703
2928
|
/**
|
|
2704
2929
|
* Helper type to extract schema from client
|
|
2705
2930
|
*/
|
|
2706
2931
|
type ClientSchema<T extends TypedRelyIOClient<AnySchemaDefinition>> = T extends TypedRelyIOClient<infer TSchema> ? TSchema : never;
|
|
2707
2932
|
|
|
2708
|
-
export {
|
|
2933
|
+
export { type FullTextConfig as $, AutocompleteBuilder as A, type SimilarResult as B, type ClientSchema as C, type SimilarResponse as D, type ExtendedQueryResult as E, type SearchFilter as F, type SearchFields as G, HttpClient as H, BatchClient as I, BatchBuilder as J, type BatchMethod as K, type BatchOperation as L, type BatchOptions as M, type BatchOperationResult as N, type BatchSummary as O, type BatchResponse as P, AdhocQueryClient as Q, type Register as R, type SendOptions as S, TypedRelyIOClient as T, AdhocQueryBuilder as U, type FetchBlock as V, type AggregateBlock as W, type AggregateMetric as X, type SearchBlock as Y, type SimilarBlock as Z, type FilterValue as _, type TypedClientConfig as a, type AdhocQueryDefinition as a0, type AdhocQueryOptions as a1, type QueryMetadata as a2, type AdhocQueryResult as a3, AssetClient as a4, AssetFileBuilder as a5, AssetUploadBuilder as a6, isAssetEntry as a7, type AssetVisibility as a8, type FileStatus as a9, validateFile as aA, type FileBackend as aa, type AssetFileBlock as ab, type AssetFileExtracted as ac, type AssetUrls as ad, type AssetEntryResponse as ae, type PopulatedAssetReference as af, type PresignInput as ag, type PresignResult as ah, type ConfirmInput as ai, type ConfirmResult as aj, type ResolveUrlInput as ak, type ResolveUrlResult as al, type CreateAssetOptions as am, type WaitUntilReadyOptions as an, type MultipartCreateResult as ao, type MultipartPart as ap, type MultipartTarget as aq, type UploadProgress as ar, ResourceNotFoundError as as, ResourceConflictError as at, ResourceExpiredError as au, isResourceNotFound as av, type FileErrorCode as aw, FileUploadError as ax, FileValidationError as ay, type FileValidationConstraints as az, type RegisteredSchema as b, createClient as c, type ConditionalWriteOptions as d, entityTagOf as e, type RetryableWriteOptions as f, ChangesExpiredError as g, type Change as h, type ChangesOptions as i, type ChangesExpiredReason as j, ContentClient as k, SingletonClient as l, SettingsClient as m, ContentQueryBuilder as n, ContentByIdBuilder as o, type ChildrenOptions as p, type SingletonFetchOptions as q, type SettingsFetchOptions as r, SearchClient as s, SearchBuilder as t, SimilarBuilder as u, type SearchMode as v, type SearchResultItem as w, type SearchResponse as x, type AutocompleteSuggestion as y, type AutocompleteResponse as z };
|