@escape-game-over/atlas 0.1.74 → 0.1.76
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/docs/client-scripts.md +3 -1
- package/package.json +2 -2
- package/src/address-formats.ts +102 -2
- package/src/astro/google-event.ts +16 -14
- package/src/contact.ts +54 -14
- package/src/index.ts +3 -0
package/docs/client-scripts.md
CHANGED
|
@@ -581,7 +581,9 @@ googleEvent("form_submissions_contact"); // does not compile
|
|
|
581
581
|
A name nobody declared does not compile, so a typo cannot quietly become a
|
|
582
582
|
second event in a report — which is why this is not a `string` with the standard
|
|
583
583
|
names offered for autocomplete. Data declared with a required field is required
|
|
584
|
-
at every call.
|
|
584
|
+
at every call. A Google declaration may reuse a recommended name —
|
|
585
|
+
`generate_lead` with an agency's own parameters, say — and then takes what was
|
|
586
|
+
declared instead of GA4's. The interfaces are `GoogleCustomEvents`, `MetaCustomEvents`,
|
|
585
587
|
`TikTokCustomEvents`, `UmamiEvents`, `DripEvents` and `ClarityEvents`; Clarity
|
|
586
588
|
carries a name only, so its entries are all `undefined`. Snap and Axon take no
|
|
587
589
|
declarations because they accept no names but their own.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@escape-game-over/atlas",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.76",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Typed, data-driven machinery for static multi-locale, multi-deployment Astro sites.",
|
|
6
6
|
"private": false,
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@biomejs/biome": "2.5.15",
|
|
61
|
-
"@types/node": "26.6.
|
|
61
|
+
"@types/node": "26.6.4",
|
|
62
62
|
"@vitest/coverage-istanbul": "5.0.3",
|
|
63
63
|
"astro": "7.3.5",
|
|
64
64
|
"typescript": "6.0.3",
|
package/src/address-formats.ts
CHANGED
|
@@ -26,7 +26,28 @@ export type AddressPart =
|
|
|
26
26
|
export type AddressLayout = readonly (readonly AddressPart[])[];
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* The script an address is written in: the country's own, or Latin letters.
|
|
30
|
+
* Some countries order the two differently: `東京都` before the street, but
|
|
31
|
+
* `Tokyo` after it.
|
|
32
|
+
*/
|
|
33
|
+
export type AddressScript = "local" | "latin";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* How a country lays out an address written in `script`: its Latin-script
|
|
37
|
+
* layout where it has one of its own, else the local one.
|
|
38
|
+
*/
|
|
39
|
+
export function addressLayout(
|
|
40
|
+
country: CountryCode,
|
|
41
|
+
script: AddressScript = "local"
|
|
42
|
+
): AddressLayout {
|
|
43
|
+
return (
|
|
44
|
+
(script === "latin" ? latinAddressLayout(country) : undefined) ??
|
|
45
|
+
localAddressLayout(country)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* How a country lays out an address in its own script.
|
|
30
51
|
*
|
|
31
52
|
* Converted once from Google's address metadata, the dataset behind
|
|
32
53
|
* libaddressinput (Apache License 2.0), fetched 2026-10-02 one country at a
|
|
@@ -50,7 +71,7 @@ export type AddressLayout = readonly (readonly AddressPart[])[];
|
|
|
50
71
|
* To update one, take its format from that address again and convert it the
|
|
51
72
|
* same way. A country listed twice is caught by Biome's `noDuplicateCase`.
|
|
52
73
|
*/
|
|
53
|
-
|
|
74
|
+
function localAddressLayout(country: CountryCode): AddressLayout {
|
|
54
75
|
switch (country) {
|
|
55
76
|
case "AD":
|
|
56
77
|
case "AT":
|
|
@@ -667,3 +688,82 @@ export function addressLayout(country: CountryCode): AddressLayout {
|
|
|
667
688
|
return [[{ field: "street" }], [{ field: "locality" }]];
|
|
668
689
|
}
|
|
669
690
|
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* How a country lays out an address in Latin letters, where that is not its
|
|
694
|
+
* local layout; `undefined` where it is.
|
|
695
|
+
*
|
|
696
|
+
* Google's `lfmt` field, from the same metadata and converted the same way as
|
|
697
|
+
* `localAddressLayout`. Fourteen countries have one; only these six differ from
|
|
698
|
+
* their `fmt` once the fields `PostalAddress` does not carry are dropped. The
|
|
699
|
+
* other eight (AE, AM, EG, MO, RU, TH, UA, VN) fall through to the local one.
|
|
700
|
+
*/
|
|
701
|
+
function latinAddressLayout(country: CountryCode): AddressLayout | undefined {
|
|
702
|
+
switch (country) {
|
|
703
|
+
case "CN":
|
|
704
|
+
case "KP":
|
|
705
|
+
return [
|
|
706
|
+
[{ field: "street" }],
|
|
707
|
+
[{ field: "locality" }],
|
|
708
|
+
[{ field: "region" }, { field: "postalCode", separator: ", " }],
|
|
709
|
+
];
|
|
710
|
+
case "HK":
|
|
711
|
+
return [
|
|
712
|
+
[{ field: "street" }],
|
|
713
|
+
[{ field: "locality" }],
|
|
714
|
+
[{ field: "region" }],
|
|
715
|
+
];
|
|
716
|
+
case "JP":
|
|
717
|
+
return [
|
|
718
|
+
[{ field: "street" }, { field: "region", separator: ", " }],
|
|
719
|
+
[{ field: "postalCode" }],
|
|
720
|
+
];
|
|
721
|
+
case "KR":
|
|
722
|
+
return [
|
|
723
|
+
[{ field: "street" }],
|
|
724
|
+
[{ field: "locality" }],
|
|
725
|
+
[{ field: "region" }],
|
|
726
|
+
[{ field: "postalCode" }],
|
|
727
|
+
];
|
|
728
|
+
case "TW":
|
|
729
|
+
return [
|
|
730
|
+
[{ field: "street" }],
|
|
731
|
+
[
|
|
732
|
+
{ field: "locality" },
|
|
733
|
+
{ field: "region", separator: ", " },
|
|
734
|
+
{ field: "postalCode", separator: " " },
|
|
735
|
+
],
|
|
736
|
+
];
|
|
737
|
+
default:
|
|
738
|
+
return undefined;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* How a country writes its address on one line: the groups `addressLine`
|
|
744
|
+
* joins, in the order a sentence or a listing runs them.
|
|
745
|
+
*
|
|
746
|
+
* `addressLayout` for every country but those below, where a line of text runs
|
|
747
|
+
* in another order than the envelope. Google's metadata has envelope layouts
|
|
748
|
+
* only, so these are written by hand; each says why.
|
|
749
|
+
*/
|
|
750
|
+
export function inlineAddressLayout(
|
|
751
|
+
country: CountryCode,
|
|
752
|
+
script: AddressScript = "local"
|
|
753
|
+
): AddressLayout {
|
|
754
|
+
switch (country) {
|
|
755
|
+
// The envelope goes town, street, postal code, each on its own line; a
|
|
756
|
+
// line of text goes postal code and town first, the way the company
|
|
757
|
+
// register writes it: `1132 Budapest, Victor Hugo utca 16`.
|
|
758
|
+
case "HU":
|
|
759
|
+
return [
|
|
760
|
+
[
|
|
761
|
+
{ field: "postalCode" },
|
|
762
|
+
{ field: "locality", separator: " " },
|
|
763
|
+
],
|
|
764
|
+
[{ field: "street" }],
|
|
765
|
+
];
|
|
766
|
+
default:
|
|
767
|
+
return addressLayout(country, script);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
@@ -78,22 +78,24 @@ export interface GoogleEventData {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
|
-
* A
|
|
82
|
-
*
|
|
83
|
-
*
|
|
81
|
+
* A declared event takes what the project declared — checked first, so a
|
|
82
|
+
* project can declare a recommended name too, when its Tag Manager wants that
|
|
83
|
+
* name with its own parameters (an agency's `generate_lead`, say). Otherwise a
|
|
84
|
+
* recommended event takes GA4's parameters; `purchase` without its three
|
|
85
|
+
* reports a sale of nothing, possibly twice.
|
|
84
86
|
*/
|
|
85
87
|
type GoogleEventArgs<E extends GoogleEventName> =
|
|
86
|
-
E extends
|
|
87
|
-
? E
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
E extends DeclaredEvent<GoogleCustomEvents>
|
|
89
|
+
? EventDataArgs<GoogleCustomEvents[E]>
|
|
90
|
+
: E extends "purchase"
|
|
91
|
+
? [
|
|
92
|
+
data: GoogleEventData & {
|
|
93
|
+
value: number;
|
|
94
|
+
currency: CurrencyCode;
|
|
95
|
+
transaction_id: string;
|
|
96
|
+
},
|
|
97
|
+
]
|
|
98
|
+
: [data?: GoogleEventData];
|
|
97
99
|
|
|
98
100
|
/**
|
|
99
101
|
* Records an event with Google — a lead sent, a booking made — through
|
package/src/contact.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type AddressLayout,
|
|
3
|
+
type AddressScript,
|
|
4
|
+
addressLayout,
|
|
5
|
+
inlineAddressLayout,
|
|
6
|
+
} from "./address-formats.ts";
|
|
2
7
|
import type { CountryCode } from "./countries.ts";
|
|
3
8
|
import type { Digit } from "./types.ts";
|
|
4
9
|
import { warn } from "./warn.ts";
|
|
@@ -334,10 +339,56 @@ export interface PostalAddress {
|
|
|
334
339
|
* own: no postal code, no `CH-`. Letter case is the caller's: some countries
|
|
335
340
|
* want the town in capitals on an envelope, which is not how a page should
|
|
336
341
|
* print it.
|
|
342
|
+
*
|
|
343
|
+
* `script` is the script the address is written in, which the caller knows and
|
|
344
|
+
* the record does not: a Tokyo address in Latin letters runs street first,
|
|
345
|
+
* `["1-1 Chiyoda, Tokyo", "100-0001"]`, where in Japanese it runs prefecture
|
|
346
|
+
* first. Only the six countries Google gives a different Latin layout care.
|
|
337
347
|
*/
|
|
338
|
-
export function addressLines(
|
|
348
|
+
export function addressLines(
|
|
349
|
+
address: PostalAddress,
|
|
350
|
+
options: AddressFormatOptions = {}
|
|
351
|
+
): readonly string[] {
|
|
352
|
+
return render(address, addressLayout(address.country, options.script));
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/** How `addressLines` writes an address. */
|
|
356
|
+
export interface AddressFormatOptions {
|
|
357
|
+
/** The script the address is written in. Defaults to `"local"`. */
|
|
358
|
+
readonly script?: AddressScript;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/** How `addressLine` writes an address. */
|
|
362
|
+
export interface AddressLineOptions extends AddressFormatOptions {
|
|
363
|
+
/** Between the groups the line joins. Defaults to `", "`. */
|
|
364
|
+
readonly separator?: string;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* The address on one line, for where there is room for only one: a venue card,
|
|
369
|
+
* an `llms.txt` entry.
|
|
370
|
+
*
|
|
371
|
+
* Not always `addressLines` joined: where a country writes a line of text in
|
|
372
|
+
* another order than an envelope, it follows the line of text. Hungary's
|
|
373
|
+
* envelope goes `Budapest` / `Victor Hugo utca 16` / `1132`; this gives `1132
|
|
374
|
+
* Budapest, Victor Hugo utca 16`.
|
|
375
|
+
*/
|
|
376
|
+
export function addressLine(
|
|
377
|
+
address: PostalAddress,
|
|
378
|
+
options: AddressLineOptions = {}
|
|
379
|
+
): string {
|
|
380
|
+
const { script, separator = ", " } = options;
|
|
381
|
+
return render(address, inlineAddressLayout(address.country, script)).join(
|
|
382
|
+
separator
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function render(
|
|
387
|
+
address: PostalAddress,
|
|
388
|
+
layout: AddressLayout
|
|
389
|
+
): readonly string[] {
|
|
339
390
|
const lines: string[] = [];
|
|
340
|
-
for (const parts of
|
|
391
|
+
for (const parts of layout) {
|
|
341
392
|
let line = "";
|
|
342
393
|
for (const part of parts) {
|
|
343
394
|
if ("text" in part) {
|
|
@@ -353,14 +404,3 @@ export function addressLines(address: PostalAddress): readonly string[] {
|
|
|
353
404
|
}
|
|
354
405
|
return lines;
|
|
355
406
|
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* `addressLines` on one line, for where there is room for only one: a venue
|
|
359
|
-
* card, an `llms.txt` entry.
|
|
360
|
-
*/
|
|
361
|
-
export function addressLine(
|
|
362
|
-
address: PostalAddress,
|
|
363
|
-
separator: string = ", "
|
|
364
|
-
): string {
|
|
365
|
-
return addressLines(address).join(separator);
|
|
366
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
+
export type { AddressScript } from "./address-formats.ts";
|
|
15
16
|
export {
|
|
16
17
|
CONSENT_CATEGORIES,
|
|
17
18
|
CONSENT_MONTHS,
|
|
@@ -51,6 +52,8 @@ export type {
|
|
|
51
52
|
SiteConfigShape,
|
|
52
53
|
} from "./config.ts";
|
|
53
54
|
export {
|
|
55
|
+
type AddressFormatOptions,
|
|
56
|
+
type AddressLineOptions,
|
|
54
57
|
addressLine,
|
|
55
58
|
addressLines,
|
|
56
59
|
assertCoordinates,
|