@nitida/asset-client 0.18.1 → 0.19.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/AGENTS.md +20 -2
- package/LICENSE +21 -0
- package/README.md +10 -0
- package/SECURITY.md +56 -0
- package/dist/index.cjs +32 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +54 -2
- package/dist/index.d.ts +54 -2
- package/dist/index.js +28 -3
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/src/access.ts +22 -2
- package/src/index.ts +61 -0
package/src/index.ts
CHANGED
|
@@ -80,6 +80,67 @@ export type RequestablePreset =
|
|
|
80
80
|
// compact `presets` wire string — so it is here and not on VariantPreset.
|
|
81
81
|
| "probe";
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* The same set as {@link RequestablePreset}, at RUNTIME.
|
|
85
|
+
*
|
|
86
|
+
* The type stops the mistake in TypeScript. It cannot stop it anywhere else,
|
|
87
|
+
* and "anywhere else" is where it keeps happening: a preset list assembled
|
|
88
|
+
* from config, from a route body, from JSON, or from a script's argv arrives
|
|
89
|
+
* as `string[]`, and the only way past the type was a cast.
|
|
90
|
+
*
|
|
91
|
+
* Measured in neo-real-estate on 2026-08-23, in THREE independent files:
|
|
92
|
+
*
|
|
93
|
+
* presets: [...opts.presets] as VariantPreset[]
|
|
94
|
+
*
|
|
95
|
+
* — a blind cast, and to the wrong type at that: `VariantPreset` includes
|
|
96
|
+
* `hls` and `mp3`, which are precisely the two you may not ask for. Every one
|
|
97
|
+
* of those casts would have compiled a request the server answers 400.
|
|
98
|
+
*
|
|
99
|
+
* So the narrowing lives here, once, instead of being re-invented per repo.
|
|
100
|
+
*/
|
|
101
|
+
export const REQUESTABLE_PRESETS: readonly RequestablePreset[] = [
|
|
102
|
+
"thumb",
|
|
103
|
+
"sm",
|
|
104
|
+
"md",
|
|
105
|
+
"lg",
|
|
106
|
+
"xl",
|
|
107
|
+
"original",
|
|
108
|
+
"poster",
|
|
109
|
+
"video",
|
|
110
|
+
"aiproxy",
|
|
111
|
+
"probe",
|
|
112
|
+
] as const;
|
|
113
|
+
|
|
114
|
+
/** Type guard for a single value. */
|
|
115
|
+
export const isRequestablePreset = (v: string): v is RequestablePreset =>
|
|
116
|
+
(REQUESTABLE_PRESETS as readonly string[]).includes(v);
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Narrow a `string[]` to the presets the server can actually produce, or throw
|
|
120
|
+
* naming the offender.
|
|
121
|
+
*
|
|
122
|
+
* Throws rather than filtering silently, for the same reason the seven URL
|
|
123
|
+
* builders throw on a private asset: **a silence reads as "you can't"**. A
|
|
124
|
+
* caller that asked for `hls` wants an HLS ladder; dropping it quietly returns
|
|
125
|
+
* a 200 and no ladder, and the 404 lands later and somewhere else. The error
|
|
126
|
+
* names the value, says why the server cannot make it, and lists what it can.
|
|
127
|
+
*/
|
|
128
|
+
export const toRequestablePresets = (
|
|
129
|
+
input: readonly string[],
|
|
130
|
+
): RequestablePreset[] => {
|
|
131
|
+
const bad = input.filter((p) => !isRequestablePreset(p));
|
|
132
|
+
if (bad.length > 0) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`Cannot request ${bad.map((b) => `"${b}"`).join(", ")}. ` +
|
|
135
|
+
"`hls` and `mp3` are things a variant can BE, not things you may ask " +
|
|
136
|
+
"for — the server derives them itself (hls when a video is " +
|
|
137
|
+
"transcoded, mp3 alongside any audio original). " +
|
|
138
|
+
`Requestable: ${REQUESTABLE_PRESETS.join(", ")}.`,
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
return input as RequestablePreset[];
|
|
142
|
+
};
|
|
143
|
+
|
|
83
144
|
/** 1-char alias used in storage keys / wire `presets` string. */
|
|
84
145
|
export const PRESET_SHORT: Record<VariantPreset, string> = {
|
|
85
146
|
thumb: "q",
|