@volter/twin-googlefonts 0.0.0-stage → 1.0.2
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/LICENSE +202 -0
- package/README.md +15 -2
- package/api/spec/SOURCE.md +17 -0
- package/api/spec/discovery.json +306 -0
- package/api/spec/openapi.json +647 -0
- package/api/spec/sources.json +16 -0
- package/api/src/fetch.ts +16 -0
- package/api/src/generated/surface.gen.json +1 -0
- package/api/src/generated/ui.gen.json +1 -0
- package/api/src/index.ts +3 -0
- package/api/src/manifest.ts +31 -0
- package/api/src/semantics/doors.ts +135 -0
- package/api/src/semantics/index.ts +8 -0
- package/api/src/semantics/shared.ts +1 -0
- package/api/src/semantics/states.ts +6 -0
- package/api/src/semantics/webfonts.ts +32 -0
- package/assets/spec/SOURCE.md +11 -0
- package/assets/spec/openapi.json +162 -0
- package/assets/spec/sources.json +1 -0
- package/assets/src/fetch.ts +14 -0
- package/assets/src/generated/surface.gen.json +1 -0
- package/assets/src/generated/ui.gen.json +1 -0
- package/assets/src/index.ts +3 -0
- package/assets/src/manifest.ts +19 -0
- package/assets/src/semantics/index.ts +10 -0
- package/assets/src/semantics/l.ts +4 -0
- package/assets/src/semantics/s.ts +4 -0
- package/assets/src/semantics/shared.ts +13 -0
- package/css/spec/SOURCE.md +17 -0
- package/css/spec/openapi.json +142 -0
- package/css/spec/sources.json +1 -0
- package/css/src/fetch.ts +14 -0
- package/css/src/generated/surface.gen.json +1 -0
- package/css/src/generated/ui.gen.json +1 -0
- package/css/src/index.ts +3 -0
- package/css/src/manifest.ts +19 -0
- package/css/src/semantics/css.ts +19 -0
- package/css/src/semantics/css2.ts +20 -0
- package/css/src/semantics/index.ts +10 -0
- package/css/src/semantics/shared.ts +1 -0
- package/dist/api/spec/SOURCE.md +17 -0
- package/dist/api/spec/discovery.json +306 -0
- package/dist/api/spec/openapi.json +647 -0
- package/dist/api/spec/sources.json +16 -0
- package/dist/api/src/fetch.d.ts +2 -0
- package/dist/api/src/fetch.js +15 -0
- package/dist/api/src/generated/surface.gen.json +1 -0
- package/dist/api/src/generated/ui.gen.json +1 -0
- package/dist/api/src/index.d.ts +2 -0
- package/dist/api/src/index.js +3 -0
- package/dist/api/src/manifest.d.ts +2 -0
- package/dist/api/src/manifest.js +29 -0
- package/dist/api/src/semantics/doors.d.ts +3 -0
- package/dist/api/src/semantics/doors.js +142 -0
- package/dist/api/src/semantics/index.d.ts +2 -0
- package/dist/api/src/semantics/index.js +4 -0
- package/dist/api/src/semantics/shared.d.ts +1 -0
- package/dist/api/src/semantics/shared.js +1 -0
- package/dist/api/src/semantics/states.d.ts +8 -0
- package/dist/api/src/semantics/states.js +6 -0
- package/dist/api/src/semantics/webfonts.d.ts +2 -0
- package/dist/api/src/semantics/webfonts.js +34 -0
- package/dist/assets/spec/SOURCE.md +11 -0
- package/dist/assets/spec/openapi.json +162 -0
- package/dist/assets/spec/sources.json +1 -0
- package/dist/assets/src/fetch.d.ts +2 -0
- package/dist/assets/src/fetch.js +13 -0
- package/dist/assets/src/generated/surface.gen.json +1 -0
- package/dist/assets/src/generated/ui.gen.json +1 -0
- package/dist/assets/src/index.d.ts +2 -0
- package/dist/assets/src/index.js +3 -0
- package/dist/assets/src/manifest.d.ts +2 -0
- package/dist/assets/src/manifest.js +17 -0
- package/dist/assets/src/semantics/index.d.ts +2 -0
- package/dist/assets/src/semantics/index.js +6 -0
- package/dist/assets/src/semantics/l.d.ts +2 -0
- package/dist/assets/src/semantics/l.js +3 -0
- package/dist/assets/src/semantics/s.d.ts +2 -0
- package/dist/assets/src/semantics/s.js +3 -0
- package/dist/assets/src/semantics/shared.d.ts +2 -0
- package/dist/assets/src/semantics/shared.js +13 -0
- package/dist/css/spec/SOURCE.md +17 -0
- package/dist/css/spec/openapi.json +142 -0
- package/dist/css/spec/sources.json +1 -0
- package/dist/css/src/fetch.d.ts +2 -0
- package/dist/css/src/fetch.js +13 -0
- package/dist/css/src/generated/surface.gen.json +1 -0
- package/dist/css/src/generated/ui.gen.json +1 -0
- package/dist/css/src/index.d.ts +2 -0
- package/dist/css/src/index.js +3 -0
- package/dist/css/src/manifest.d.ts +2 -0
- package/dist/css/src/manifest.js +16 -0
- package/dist/css/src/semantics/css.d.ts +2 -0
- package/dist/css/src/semantics/css.js +19 -0
- package/dist/css/src/semantics/css2.d.ts +2 -0
- package/dist/css/src/semantics/css2.js +21 -0
- package/dist/css/src/semantics/index.d.ts +2 -0
- package/dist/css/src/semantics/index.js +6 -0
- package/dist/css/src/semantics/shared.d.ts +1 -0
- package/dist/css/src/semantics/shared.js +1 -0
- package/dist/generated/pack-facts.json +68 -0
- package/dist/journeys/customer-life.json +544 -0
- package/dist/journeys/decisions.json +64 -0
- package/dist/journeys/demand.json +101 -0
- package/dist/journeys/first-use.json +20 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +22 -0
- package/dist/src/fetch.d.ts +2 -0
- package/dist/src/fetch.js +10 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +15 -0
- package/dist/src/manifest.d.ts +2 -0
- package/dist/src/manifest.js +27 -0
- package/dist/src/semantics/seed.d.ts +2 -0
- package/dist/src/semantics/seed.js +181 -0
- package/dist/src/semantics/shared.d.ts +9 -0
- package/dist/src/semantics/shared.js +23 -0
- package/dist/src/server.d.ts +7 -0
- package/dist/src/server.js +7 -0
- package/generated/pack-facts.json +68 -0
- package/journeys/customer-life.json +544 -0
- package/journeys/decisions.json +64 -0
- package/journeys/demand.json +101 -0
- package/journeys/first-use.json +20 -0
- package/package.json +57 -4
- package/src/cli.ts +22 -0
- package/src/fetch.ts +11 -0
- package/src/index.ts +17 -0
- package/src/manifest.ts +29 -0
- package/src/semantics/seed.ts +183 -0
- package/src/semantics/shared.ts +25 -0
- package/src/server.ts +8 -0
- package/vendor/Inter-OFL.txt +93 -0
- package/vendor/OFL.txt +94 -0
- package/vendor/SOURCE.md +40 -0
- package/vendor/antic.json +93 -0
- package/vendor/inputs.json +460 -0
- package/vendor/inter-variable.json +52 -0
- package/vendor/inter.json +44 -0
- package/vendor/noto-sans-sc-text.json +24 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"about": "Source-bound decisions before handler implementation; each lane shares one googlefonts store. Qualification remains separate.",
|
|
3
|
+
"decisions": [
|
|
4
|
+
{
|
|
5
|
+
"operation": "webfonts.webfonts.list",
|
|
6
|
+
"lane": "api",
|
|
7
|
+
"mechanism": "handler",
|
|
8
|
+
"demand": "Pinned production startup",
|
|
9
|
+
"why": "Read unchanged vendor font items in the stored catalog order; alpha/date/style sorting and family/subset/category filtering consume the Developer API fields. first-use axios catalog call asserts the list and derives all later selections from its returned item. Never return a full-live-catalog claim."
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"operation": "getStylesheet",
|
|
13
|
+
"lane": "css",
|
|
14
|
+
"mechanism": "handler",
|
|
15
|
+
"demand": "All five pinned config.ts UAs",
|
|
16
|
+
"why": "Use exact published CSS per request/UA, with the real font-family/style/weight/src consumed by fetchCSS; first-use downloads every returned src. Unsupported representations answer a refusal."
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"operation": "getStylesheet2",
|
|
20
|
+
"lane": "css",
|
|
21
|
+
"mechanism": "handler",
|
|
22
|
+
"demand": "Dub's Inter weights and Rallly's CJK text subsets, both from a server; Rallly's and Cal.diy's next/font/google build of Inter's variable weights, with next/font's browser User-Agent",
|
|
23
|
+
"why": "Use the exact published CSS per ordered CSS2 query and User-Agent; a non-browser agent without its own representation reads the one published for no agent, as Google answered the same CSS to none, node and undici. Unpublished families, text subsets and browser representations answer a refusal; text= and display= given twice, or another parameter, are a bad request."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"operation": "getFontFile",
|
|
27
|
+
"lane": "assets",
|
|
28
|
+
"mechanism": "handler",
|
|
29
|
+
"demand": "Archive stream for returned /s URL; the woff2 faces next/font/google self-hosts at build",
|
|
30
|
+
"why": "Resolve the actual vendor URL to its resource blob and preserve Content-Type/bytes; no conversion or placeholder font."
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"operation": "getLegacyFontFile",
|
|
34
|
+
"lane": "assets",
|
|
35
|
+
"mechanism": "handler",
|
|
36
|
+
"demand": "EOT/SVG src uses /l/font query URL",
|
|
37
|
+
"why": "Same blob mechanism; preserve kit/skey/v and ignore the SVG fragment as HTTP does."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"operation": "door:appCredentials",
|
|
41
|
+
"lane": "api",
|
|
42
|
+
"mechanism": "door",
|
|
43
|
+
"demand": "World boot credential fill",
|
|
44
|
+
"why": "Google issues the key outside the Fonts read-only API: a standard API key belongs to a Google Cloud project, made on that project's Credentials page, and associates each request with the project for billing and quota; the Developer API takes it as key= and nothing else. The door keeps a project per World organization (ctx.tenant) and one key per deployment under it (ctx.accountKey), drawn from the World's seed so a World returned to its seed issues the same key; only its hash is recorded.",
|
|
45
|
+
"sourceRules": [
|
|
46
|
+
{
|
|
47
|
+
"source": "https://developers.google.com/fonts/docs/developer_api",
|
|
48
|
+
"means": "the Developer API identifies the application by an API key, key= on every request, made on the Cloud console's Credentials page"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"source": "https://docs.cloud.google.com/docs/authentication/api-keys",
|
|
52
|
+
"means": "a standard API key associates a request with a project for billing and quota; keys are listed and created per project (console, gcloud services api-keys, keys.create)"
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"operation": "door:publishCatalog",
|
|
58
|
+
"lane": "api",
|
|
59
|
+
"mechanism": "door",
|
|
60
|
+
"demand": "Vendor-side prerequisite for a reference-data World",
|
|
61
|
+
"why": "There is no Developer API create-font endpoint. Validate a complete vendor-shaped catalog/CSS/blob publication before recording it; the default seed and first-use supply retained genuine bytes. This is an explicit publisher door, not a handler pretending a vendor mutation."
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"measured": "2026-10-12: source-only read of every non-test server TS file at ff245dc87cfcbaeacd4120cf1b4a7443b59db42f, image 77e89ea9. No application or vendor-key request was executed. The normal start fetches the Developer API catalog; font detail/download reaches CSS for all five configured UAs and downloads its returned URLs. GOOGLE_FONTS_USE_TEST_JSON is excluded, and is not set. 2026-10-15: source-only read of Dub 7e01013 and Rallly 3e63239 Open Graph routes; Google's CSS2 answers retained with no User-Agent, node and undici (vendor/inter.json).",
|
|
3
|
+
"applications": [
|
|
4
|
+
{
|
|
5
|
+
"name": "majodev/google-webfonts-helper",
|
|
6
|
+
"commit": "ff245dc87cfcbaeacd4120cf1b4a7443b59db42f",
|
|
7
|
+
"client": "axios 1.20.0, unchanged production server",
|
|
8
|
+
"backend": [
|
|
9
|
+
{
|
|
10
|
+
"call": "GET www.googleapis.com/webfonts/v1/webfonts?sort=popularity&key=<issued key>",
|
|
11
|
+
"operation": "webfonts.webfonts.list",
|
|
12
|
+
"evidence": "server/logic/fetchGoogleFonts.ts:62"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"call": "GET fonts.googleapis.com/css?family=<family>:<variant>&subset=<subsets>, User-Agent from config.ts",
|
|
16
|
+
"operation": "getStylesheet",
|
|
17
|
+
"evidence": "server/logic/fetchCSS.ts:19"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"call": "GET fonts.gstatic.com/s/... bytes returned in the CSS",
|
|
21
|
+
"operation": "getFontFile",
|
|
22
|
+
"evidence": "server/logic/fetchFontSubsetArchive.ts:104"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"call": "GET fonts.gstatic.com/l/font?kit=...&skey=...&v=... for EOT/SVG representations",
|
|
26
|
+
"operation": "getLegacyFontFile",
|
|
27
|
+
"evidence": "server/logic/fetchFontURLs.ts:61; vendor/inputs.json retained Google EOT/SVG CSS"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "dubinc/dub",
|
|
33
|
+
"commit": "7e01013",
|
|
34
|
+
"client": "Next.js server fetch, no browser User-Agent",
|
|
35
|
+
"backend": [
|
|
36
|
+
{
|
|
37
|
+
"call": "GET fonts.googleapis.com/css2?family=Inter:wght@<500|600|700>",
|
|
38
|
+
"operation": "getStylesheet2",
|
|
39
|
+
"evidence": "apps/web/app/api/og/load-google-font.ts:2-3; callers apps/web/app/api/og/program/route.tsx:29, analytics/route.tsx:18, partner-earnings/route.tsx:27, program/categories/route.tsx:34, partner-rewind/route.tsx:29"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"call": "GET fonts.gstatic.com/s/... truetype URL returned in the CSS",
|
|
43
|
+
"operation": "getFontFile",
|
|
44
|
+
"evidence": "apps/web/app/api/og/load-google-font.ts:9"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "lukevella/rallly",
|
|
50
|
+
"commit": "3e63239",
|
|
51
|
+
"client": "Next.js server fetch, no browser User-Agent",
|
|
52
|
+
"backend": [
|
|
53
|
+
{
|
|
54
|
+
"call": "GET fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@<400|700>&text=<rendered CJK text>",
|
|
55
|
+
"operation": "getStylesheet2",
|
|
56
|
+
"evidence": "apps/landing/src/app/[locale]/opengraph-image.tsx:26-27 (CJK locales only)"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"call": "GET fonts.gstatic.com truetype URL returned in the CSS",
|
|
60
|
+
"operation": "getFontFile",
|
|
61
|
+
"evidence": "apps/landing/src/app/[locale]/opengraph-image.tsx:38"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "lukevella/rallly",
|
|
67
|
+
"commit": "195877a38de4fb96bce921011668871da1121174",
|
|
68
|
+
"client": "next build (Next.js 16.1.6, Turbopack's next/font: crates/next-core/src/next_font/google, User-Agent USER_AGENT_FOR_GOOGLE_FONTS)",
|
|
69
|
+
"backend": [
|
|
70
|
+
{
|
|
71
|
+
"call": "GET fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap",
|
|
72
|
+
"operation": "getStylesheet2",
|
|
73
|
+
"evidence": "apps/web/src/app/[locale]/layout.tsx:8,31-34 (Inter, subsets latin, display swap); also at 65fb551012078fc3058d8a23b3fa4be1846fd056 (layout.tsx:8,28-31)"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"call": "GET fonts.gstatic.com/s/inter/v20/... woff2, each URL returned in the CSS",
|
|
77
|
+
"operation": "getFontFile",
|
|
78
|
+
"evidence": "the same build"
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "calcom/cal.diy",
|
|
84
|
+
"commit": "5918e66cc56b3a36c1e7205c7fc00eaad50dece8",
|
|
85
|
+
"client": "next build (Next.js 15.5.8, next/font's packages/font/src/google/fetch-resource.ts, the same User-Agent)",
|
|
86
|
+
"backend": [
|
|
87
|
+
{
|
|
88
|
+
"call": "GET fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap",
|
|
89
|
+
"operation": "getStylesheet2",
|
|
90
|
+
"evidence": "apps/web/app/layout.tsx:2,18; apps/web/components/PageWrapper.tsx:13,36"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"call": "GET fonts.gstatic.com/s/inter/v20/... woff2, each URL returned in the CSS",
|
|
94
|
+
"operation": "getFontFile",
|
|
95
|
+
"evidence": "the same build"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"notDemanded": "OAuth, font submission/publishing UI, effects and advanced catalog capabilities are outside these client paths."
|
|
101
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"source": "majodev/google-webfonts-helper ff245dc87cfcbaeacd4120cf1b4a7443b59db42f package.json axios1.20.0 and server/logic/fetchGoogleFonts.ts, fetchCSS.ts, fetchFontSubsetArchive.ts; Google Developer API guide",
|
|
4
|
+
"about": "The default seed publishes the attributed vendor snapshot through its publisher door. The customer reads the issued key and authenticates with the real axios client, consuming metadata/CSS/src bytes. Retention re-reads without writes. This entry is not run during source construction.",
|
|
5
|
+
"files": {
|
|
6
|
+
"package.json": "{\"type\": \"module\", \"dependencies\": {\"axios\": \"1.20.0\"}}\n",
|
|
7
|
+
".env.example": "GOOGLE_FONTS_API_KEY=\n",
|
|
8
|
+
"app.mjs": "import axios from 'axios';\nimport assert from 'node:assert/strict';\nconst key = process.env.GOOGLE_FONTS_API_KEY;\nassert.ok(key, 'World-issued GOOGLE_FONTS_API_KEY is required');\nconst res = await axios.get(`https://www.googleapis.com/webfonts/v1/webfonts?sort=popularity&key=${key}`, { responseType: 'json', maxRedirects: 0 });\nassert.equal(res.data.kind, 'webfonts#webfontList');\nconst item = res.data.items.find(f => f.family === 'Antic');\nassert.ok(item); assert.ok(item.variants.includes('regular')); assert.ok(item.subsets.includes('latin'));\nconst agents = {\"0\": \"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)\", \"1\": \"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0\", \"2\": \"Mozilla/5.0 (Windows NT 6.3; rv:39.0) Gecko/20100101 Firefox/39.0\", \"3\": \"Mozilla/4.0 (iPad; CPU OS 4_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/4.1 Mobile/9A405 Safari/7534.48.3\", \"4\": \"Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) Safari/538.1 Daum/4.1\"};\nfor (const agent of Object.values(agents)) {\n const css = await axios.get('http://fonts.googleapis.com/css?family='+encodeURIComponent(item.family+':regular')+'&subset=latin', { responseType: 'text', maxRedirects: 0, headers: { Accept: 'text/css,*/*;q=0.1', 'User-Agent': agent } });\n assert.match(css.data, /@font-face/);\n const url = css.data.match(/url\\((https?:\\/\\/[^)]+)\\)/)?.[1]; assert.ok(url);\n const file = await axios.get(url.replace('http://','https://'), { responseType: 'arraybuffer', maxRedirects: 0 });\n assert.ok(file.data.length > 0); assert.ok(file.headers['content-type']);\n}\nconsole.log('Read retained Google Fonts catalog, CSS and bytes through unchanged axios calls');\n"
|
|
9
|
+
},
|
|
10
|
+
"run": [
|
|
11
|
+
"node",
|
|
12
|
+
"app.mjs"
|
|
13
|
+
],
|
|
14
|
+
"retention": {
|
|
15
|
+
"readback": [
|
|
16
|
+
"node",
|
|
17
|
+
"app.mjs"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/twin-googlefonts",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "The googlefonts twin (Protocol 3).",
|
|
5
|
+
"author": "Volter (https://github.com/volter-ai)",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/src/index.d.ts",
|
|
11
|
+
"default": "./dist/src/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"world-googlefonts": "dist/src/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"src",
|
|
19
|
+
"dist",
|
|
20
|
+
"generated",
|
|
21
|
+
"spec",
|
|
22
|
+
"css/src",
|
|
23
|
+
"css/spec",
|
|
24
|
+
"api/src",
|
|
25
|
+
"api/spec",
|
|
26
|
+
"assets/src",
|
|
27
|
+
"assets/spec",
|
|
28
|
+
"README.md",
|
|
29
|
+
"!**/*.test.ts",
|
|
30
|
+
"vendor",
|
|
31
|
+
"LICENSE",
|
|
32
|
+
"journeys/customer-life.json",
|
|
33
|
+
"journeys/decisions.json",
|
|
34
|
+
"journeys/demand.json",
|
|
35
|
+
"journeys/first-use.json"
|
|
36
|
+
],
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@volter/world-core": "^3.0.185"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=22.3"
|
|
42
|
+
},
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/volter-ai/twin-packs-p3.git",
|
|
46
|
+
"directory": "googlefonts"
|
|
47
|
+
},
|
|
48
|
+
"packageManager": "pnpm@12.15.0",
|
|
49
|
+
"devEngines": {
|
|
50
|
+
"packageManager": {
|
|
51
|
+
"name": "pnpm",
|
|
52
|
+
"version": "12.15.0",
|
|
53
|
+
"onFail": "error"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"volterRelease": {
|
|
57
|
+
"commit": "c41b6615f37f0e7d69753fd85ff9568d9f4c8174"
|
|
58
|
+
}
|
|
59
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// world-googlefonts: serve the googlefonts twin.
|
|
3
|
+
import { parseArgs } from 'node:util';
|
|
4
|
+
import { keepProcessAlive } from '@volter/world-core/lifecycle';
|
|
5
|
+
import { createGooglefontsTwinServer } from './server.ts';
|
|
6
|
+
|
|
7
|
+
const { values, positionals } = parseArgs({ options: { port: { type: 'string' }, root: { type: 'string' }, 'read-only': { type: 'boolean' }, database: { type: 'string' } }, allowPositionals: true, strict: true });
|
|
8
|
+
if (positionals.length > 1) throw new Error('Expected one command');
|
|
9
|
+
const [cmd] = positionals;
|
|
10
|
+
const port = Number(values.port ?? '0') || undefined;
|
|
11
|
+
const root = values.root;
|
|
12
|
+
const readOnly = Boolean(values['read-only']);
|
|
13
|
+
// the selected twin's private Postgres, which the runtime binds a pack declaring managedDatabase to
|
|
14
|
+
const database = values.database;
|
|
15
|
+
|
|
16
|
+
if (cmd === 'serve' || cmd === undefined) {
|
|
17
|
+
const s = await createGooglefontsTwinServer({ readOnly, ...(root ? { root } : {}), ...(port ? { port } : {}), ...(database ? { database } : {}) });
|
|
18
|
+
process.stdout.write(`googlefonts twin${readOnly ? ' [read-only]' : ''} at http://127.0.0.1:${s.port}\n`);
|
|
19
|
+
await keepProcessAlive();
|
|
20
|
+
} else {
|
|
21
|
+
process.stdout.write('Usage: world-googlefonts serve [--port N] [--root DIR] [--read-only] [--database URL]\n');
|
|
22
|
+
}
|
package/src/fetch.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// GENERATED by scripts/create-pack.ts (--init, --index): a fixed file. The kernel serves the vendor's discovery door and
|
|
2
|
+
// sends each request to the lane its manifest's routes name (architecture, "Other wires: lanes").
|
|
3
|
+
import { createVendorFetch, type DerivedFetch, type PackFetchOptions } from '@volter/world-core';
|
|
4
|
+
import { manifest } from './manifest.ts';
|
|
5
|
+
import { createApiLaneFetch, manifest as api_manifest } from '../api/src/index.ts';
|
|
6
|
+
import { createAssetsLaneFetch, manifest as assets_manifest } from '../assets/src/index.ts';
|
|
7
|
+
import { createCssLaneFetch, manifest as css_manifest } from '../css/src/index.ts';
|
|
8
|
+
|
|
9
|
+
export function createGooglefontsFetch(options: PackFetchOptions = {}): DerivedFetch {
|
|
10
|
+
return createVendorFetch(manifest, { "api": { fetch: createApiLaneFetch(options), manifest: api_manifest }, "assets": { fetch: createAssetsLaneFetch(options), manifest: assets_manifest }, "css": { fetch: createCssLaneFetch(options), manifest: css_manifest } });
|
|
11
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @volter/twin-googlefonts — the googlefonts twin (Protocol 3). A fixed file (create-pack): the descriptor is the manifest's, and the
|
|
2
|
+
// kernel derives the vendor-backed half from the generated surface, unless the manifest declares none (vendorBacked.none;
|
|
3
|
+
// architecture, "The real-system adapters").
|
|
4
|
+
import { packOf, registerPack, type DerivedSurface } from '@volter/world-core';
|
|
5
|
+
import { manifest } from './manifest.ts';
|
|
6
|
+
import { manifest as apiManifest } from '../api/src/manifest.ts';
|
|
7
|
+
import apiSurface from '../api/src/generated/surface.gen.json' with { type: 'json' };
|
|
8
|
+
import { manifest as assetsManifest } from '../assets/src/manifest.ts';
|
|
9
|
+
import assetsSurface from '../assets/src/generated/surface.gen.json' with { type: 'json' };
|
|
10
|
+
import { manifest as cssManifest } from '../css/src/manifest.ts';
|
|
11
|
+
import cssSurface from '../css/src/generated/surface.gen.json' with { type: 'json' };
|
|
12
|
+
|
|
13
|
+
export { createGooglefontsFetch } from './fetch.ts';
|
|
14
|
+
export { createGooglefontsTwinServer } from './server.ts';
|
|
15
|
+
export { manifest };
|
|
16
|
+
|
|
17
|
+
export const pack = registerPack(packOf(manifest, { "api": { manifest: apiManifest, surface: apiSurface as unknown as DerivedSurface }, "assets": { manifest: assetsManifest, surface: assetsSurface as unknown as DerivedSurface }, "css": { manifest: cssManifest, surface: cssSurface as unknown as DerivedSurface } }));
|
package/src/manifest.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Google Fonts: one store, with catalog, browser-selected CSS and font-file lanes.
|
|
2
|
+
import type { VendorManifest } from '@volter/world-core';
|
|
3
|
+
export const manifest: VendorManifest = {
|
|
4
|
+
vendor: 'googlefonts',
|
|
5
|
+
discovery: { twinOf: 'Google Fonts Developer API, the CSS and CSS2 APIs and the font URLs they return',
|
|
6
|
+
stores: 'published vendor-shaped font items, exact browser CSS, font blobs and World-issued key hashes' },
|
|
7
|
+
lanes: { routes: [
|
|
8
|
+
{ lane: 'css', host: '^fonts[.]googleapis[.]com$' },
|
|
9
|
+
{ lane: 'assets', host: '^fonts[.]gstatic[.]com$' },
|
|
10
|
+
{ lane: 'api', host: '^(www|webfonts)[.]googleapis[.]com$' },
|
|
11
|
+
], default: 'api' },
|
|
12
|
+
descriptor: {
|
|
13
|
+
protocol: '3', transport: 'rest', archetype: 'crud', bin: 'world-googlefonts',
|
|
14
|
+
resources: ['webfont', '_api_key', '_font_catalog', '_stylesheet', '_font_file'],
|
|
15
|
+
specSource: 'api/spec/SOURCE.md: unchanged Google Discovery; css/spec/SOURCE.md and assets/spec/SOURCE.md: Google documentation and retained font responses',
|
|
16
|
+
description: 'Google Fonts catalog, exact published CSS representations and genuine font bytes; a World-issued query API key. Seed data is the attributed Antic reference catalog and the CSS2 weights 500-700 of Inter, not the complete live Google catalog.',
|
|
17
|
+
// next/font/google fetches the font's stylesheet and files from Google at an app's build (twin-world architecture,
|
|
18
|
+
// Selection: a module that reaches the vendor by itself is evidence, as an SDK is)
|
|
19
|
+
adoption: { sdks: [], envStems: ['GOOGLE_FONTS'], modules: ['next/font/google'] },
|
|
20
|
+
hosts: [
|
|
21
|
+
{ host: 'www.googleapis.com', pathPattern: '^/webfonts/v1/webfonts$' },
|
|
22
|
+
{ host: 'webfonts.googleapis.com', pathPattern: '^/v1/webfonts$' },
|
|
23
|
+
{ host: 'fonts.googleapis.com', pathPattern: '^/css2?$' },
|
|
24
|
+
{ host: 'fonts.gstatic.com', pathPattern: '^/(s/|l/font$)' },
|
|
25
|
+
],
|
|
26
|
+
credentialDoor: { path: '/_twin/app-credentials', body: {}, account: { field: 'account', tenancy: 'Google Cloud project', source: 'https://developers.google.com/fonts/docs/developer_api' }, deployment: { field: 'deployment', object: 'Project API key', source: 'https://docs.cloud.google.com/docs/authentication/api-keys' }, fill: { GOOGLE_FONTS_API_KEY: 'api_key' } },
|
|
27
|
+
endpointEnvNone: 'Pinned helper hardcodes the vendor API and CSS hosts, then downloads their returned gstatic URLs. Scoped host routing preserves these URLs.',
|
|
28
|
+
},
|
|
29
|
+
};
|