@tokenoftrust/storefront-runner 4.6.2 → 4.6.3
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const SKU_MAX_LENGTH: number;
|
|
2
2
|
export const CHECKOUT_CODE_MAX_LENGTH: number;
|
|
3
3
|
export const SKU_TOKEN_MAX_LENGTH: number;
|
|
4
|
-
export type SkuRefusal = "not-string" | "empty" | "control-character" | "too-long";
|
|
4
|
+
export type SkuRefusal = "not-string" | "empty" | "control-character" | "ill-formed" | "too-long";
|
|
5
5
|
export function parseSku(value: unknown): { ok: true; sku: string } | { ok: false; reason: SkuRefusal };
|
|
6
6
|
export function isStoredSku(value: unknown): value is string;
|
|
7
7
|
export function skuKey(sku: string): string;
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A SKU is merchant data, kept exactly as the merchant wrote it. The only rewrite is trimming
|
|
5
5
|
* leading and trailing whitespace on the way in. A SKU is refused only when it is empty, carries a
|
|
6
|
-
* control character,
|
|
6
|
+
* control character, is not well-formed Unicode (a lone UTF-16 surrogate, which has no UTF-8 form
|
|
7
|
+
* and so no token), or is longer than {@link SKU_MAX_LENGTH} characters. Anything else, a space
|
|
7
8
|
* included, is a valid SKU; a space is a lint warning, never an error.
|
|
8
9
|
*
|
|
9
10
|
* Two SKUs are the same SKU when their {@link skuKey} is equal: trimmed, NBSP read as a space, and
|
|
@@ -25,6 +26,8 @@ export const CHECKOUT_CODE_MAX_LENGTH = 200;
|
|
|
25
26
|
export const SKU_TOKEN_MAX_LENGTH = SKU_MAX_LENGTH * 12;
|
|
26
27
|
|
|
27
28
|
const CONTROL = /\p{Cc}/u;
|
|
29
|
+
/** A lone surrogate: in `u` mode a paired surrogate is one code point and never matches. */
|
|
30
|
+
const LONE_SURROGATE = /\p{Cs}/u;
|
|
28
31
|
const WHITESPACE = /\s/u;
|
|
29
32
|
const TOKEN_SAFE = /^[A-Za-z0-9._-]$/;
|
|
30
33
|
const TOKEN = /^(?:[A-Za-z0-9._-]|%[0-9A-F]{2})+$/;
|
|
@@ -33,13 +36,14 @@ const TOKEN = /^(?:[A-Za-z0-9._-]|%[0-9A-F]{2})+$/;
|
|
|
33
36
|
* Read a SKU as it arrives from a merchant, a file or an import.
|
|
34
37
|
*
|
|
35
38
|
* @param {unknown} value
|
|
36
|
-
* @returns {{ ok: true, sku: string } | { ok: false, reason: "not-string" | "empty" | "control-character" | "too-long" }}
|
|
39
|
+
* @returns {{ ok: true, sku: string } | { ok: false, reason: "not-string" | "empty" | "control-character" | "ill-formed" | "too-long" }}
|
|
37
40
|
*/
|
|
38
41
|
export function parseSku(value) {
|
|
39
42
|
if (typeof value !== "string") return { ok: false, reason: "not-string" };
|
|
40
43
|
const sku = value.trim();
|
|
41
44
|
if (sku === "") return { ok: false, reason: "empty" };
|
|
42
45
|
if (CONTROL.test(sku)) return { ok: false, reason: "control-character" };
|
|
46
|
+
if (LONE_SURROGATE.test(sku)) return { ok: false, reason: "ill-formed" };
|
|
43
47
|
if ([...sku].length > SKU_MAX_LENGTH) return { ok: false, reason: "too-long" };
|
|
44
48
|
return { ok: true, sku };
|
|
45
49
|
}
|
|
@@ -92,6 +96,7 @@ const REASONS = {
|
|
|
92
96
|
"not-string": "a SKU must be text",
|
|
93
97
|
empty: "a SKU cannot be empty",
|
|
94
98
|
"control-character": "a SKU cannot contain a control character (tab, newline, ...)",
|
|
99
|
+
"ill-formed": "a SKU must be well-formed Unicode text (it contains a broken character)",
|
|
95
100
|
"too-long": `a SKU is at most ${SKU_MAX_LENGTH} characters`,
|
|
96
101
|
};
|
|
97
102
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenoftrust/storefront-runner",
|
|
3
|
-
"version": "4.6.
|
|
3
|
+
"version": "4.6.3",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"description": "World-shareable storefront runner: multi-tenant renderer on Astro/Cloudflare. No control plane.",
|
|
6
6
|
"packageManager": "pnpm@11.9.0",
|