From 5c5a72a4900c61b0cfc1633052eab3a6b7056153 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 12:00:35 -0400 Subject: [PATCH 01/25] Add wrangler; upgrade eleventy to v3.0.0. --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index fc7e4bbd..aea57bc5 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "devDependencies": { - "@11ty/eleventy": "^3.0.0-alpha.9" + "@11ty/eleventy": "^3.0.0", + "wrangler": "^4.6.0" } } From 2d24fed326c2f6acea7e56138dc633e82760b289 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 12:01:31 -0400 Subject: [PATCH 02/25] Ignore package-lock.json. --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b64c927e..0d576031 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.sw[op] .DS_Store .wrangler -node_modules +node_modules/ playground/jsonld.js -_site +_site/ +package-lock.json From a4d2d5982d03f7c5dc932e0d62e2f7bbe0e4f686 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:46:57 -0400 Subject: [PATCH 03/25] Add .editorconfig. --- .editorconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..5d47c21c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true From 731f325b3f2d0413ffe6c2d19a005b9ee02ce869 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 09:45:52 -0400 Subject: [PATCH 04/25] Add npm run pages command. This uses Cloudflare `wrangler` to serve the `_site/` folder with support for `_headers` and `_redirects` files. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index aea57bc5..e3797eb5 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "json-ld.org homepage", "scripts": { "build": "eleventy", + "pages": "wrangler pages dev _site/", "serve": "eleventy --serve", "watch": "eleventy --watch", "dev": "wrangler pages dev _site --compatibility-date=2024-04-27 --live-reload --port 8788", From 6bd39da3f568afd8eb7a713d508658d3e90391c6 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 09:48:51 -0400 Subject: [PATCH 05/25] Add info about npm run build & pages. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 34cd6856..1b7e0d93 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,10 @@ npm i npm run serve # to rebuild on changes: npm run watch +# to just build the static files to `_site/` +npm run build +# to serve `_site/` with Cloudflare Pages feature support +npm run pages # visit http://localhost:8788/ ``` Additionally, if you want to use or test the playground `http:` proxy, also run From 1a5962679e4637a96890d1c55636d53004d05f76 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 09:44:37 -0400 Subject: [PATCH 06/25] Copy over _headers and _redirects. --- .eleventy.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.eleventy.js b/.eleventy.js index 096e6fb9..d199c37d 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -16,6 +16,8 @@ module.exports = function(eleventyConfig) { eleventyConfig.addPassthroughCopy('404.html'); eleventyConfig.addPassthroughCopy('.htaccess'); eleventyConfig.addPassthroughCopy('LICENSE.md'); + eleventyConfig.addPassthroughCopy('_headers'); + eleventyConfig.addPassthroughCopy('_redirects'); eleventyConfig.addPassthroughCopy('benchmarks/**/*.{jsonld,nq,md}'); eleventyConfig.addPassthroughCopy('contexts/**/*.{htaccess,html,jsonld}'); eleventyConfig.addPassthroughCopy('contexts/{event,person,place,recipe,remote-context}'); From fd06e18a3a8f08c4fb2231e096f88dec0251f08c Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:39:03 -0400 Subject: [PATCH 07/25] Migrate root .htaccess to _redirects. Cloudflare already supports the `.jsonld` extension properly (along with any/all other registered file exstensions). Cloudflare also turns CORS on by defualt for all origins. --- .htaccess | 7 ------- _redirects | 1 + 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 .htaccess create mode 100644 _redirects diff --git a/.htaccess b/.htaccess deleted file mode 100644 index 84c18f9f..00000000 --- a/.htaccess +++ /dev/null @@ -1,7 +0,0 @@ - - ForceType application/ld+json - SetHandler default_handler - Header set Access-Control-Allow-Origin "*" - - -Redirect 302 /playground-dev /playground diff --git a/_redirects b/_redirects new file mode 100644 index 00000000..13fdff49 --- /dev/null +++ b/_redirects @@ -0,0 +1 @@ +/playground-dev /playground 302 From 0a4db616f4956d23a6d89837941d71acea79ae96 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:40:09 -0400 Subject: [PATCH 08/25] Remove images/.htaccess; handled by ignores. The `images/README.md` was already handled, so the only addition to the ignores list is the `images/Makefile`. --- .eleventy.js | 1 + images/.htaccess | 10 ---------- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 images/.htaccess diff --git a/.eleventy.js b/.eleventy.js index d199c37d..7a7dcf34 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -44,6 +44,7 @@ module.exports = function(eleventyConfig) { eleventyConfig.ignores.add('benchmarks/README.md'); eleventyConfig.ignores.add('contexts/person.html'); eleventyConfig.ignores.add('examples'); + eleventyConfig.ignores.add('images/Makefile'); eleventyConfig.ignores.add('images/README.md'); eleventyConfig.ignores.add('minutes/**/*'); eleventyConfig.ignores.add('ns/json-ld.html'); diff --git a/images/.htaccess b/images/.htaccess deleted file mode 100644 index ee8e4d25..00000000 --- a/images/.htaccess +++ /dev/null @@ -1,10 +0,0 @@ - - order allow,deny - deny from all - - - - order allow,deny - deny from all - - From 0d018e868f2b74b06224019df6300194857787c1 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:42:48 -0400 Subject: [PATCH 09/25] Migrate context/.htaccess to _headers/_redirects. --- _headers | 12 ++++++++++++ _redirects | 2 ++ contexts/.htaccess | 7 ------- 3 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 _headers delete mode 100644 contexts/.htaccess diff --git a/_headers b/_headers new file mode 100644 index 00000000..418281ad --- /dev/null +++ b/_headers @@ -0,0 +1,12 @@ +/contexts/event + Content-Type: application/ld+json + Access-Control-Allow-Origin: "*" +/contexts/person + Content-Type: application/ld+json + Access-Control-Allow-Origin: "*" +/contexts/place + Content-Type: application/ld+json + Access-Control-Allow-Origin: "*" +/contexts/recipe + Content-Type: application/ld+json + Access-Control-Allow-Origin: "*" diff --git a/_redirects b/_redirects index 13fdff49..dde88850 100644 --- a/_redirects +++ b/_redirects @@ -1 +1,3 @@ /playground-dev /playground 302 + +/contexts/schema.org.jsonld http://schema.org/ 301 diff --git a/contexts/.htaccess b/contexts/.htaccess deleted file mode 100644 index a8f948ec..00000000 --- a/contexts/.htaccess +++ /dev/null @@ -1,7 +0,0 @@ - - ForceType application/ld+json - SetHandler default_handler - Header set Access-Control-Allow-Origin "*" - - -Redirect 301 /contexts/schema.org.jsonld http://schema.org/ From 3ce6cf6995a3caa5e5afed1eddf17860466d635a Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:44:26 -0400 Subject: [PATCH 10/25] Remove broken spec/ED/.htaccess. This one never did what it intended to, judging by the commit it was added during: https://github.com/json-ld/json-ld.org/commit/5828deb01239266f8530b5769f40418b0e6af730 --- spec/ED/.htaccess | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 spec/ED/.htaccess diff --git a/spec/ED/.htaccess b/spec/ED/.htaccess deleted file mode 100644 index 3b8be4f7..00000000 --- a/spec/ED/.htaccess +++ /dev/null @@ -1,3 +0,0 @@ -RewriteEngine on -RewriteBase /json-ld.org/spec/ED -RewriteRule ^(20.*) json-ld-syntax/$1 [R=301,L] From bbcdbc921df891bad0111dc1a58db8b8da6e471c Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:45:06 -0400 Subject: [PATCH 11/25] Migrate spec/latest/.htaccess. Some handled slashes, some did not. These should match what was previously in place. --- _redirects | 12 ++++++++++++ spec/latest/.htaccess | 12 ------------ 2 files changed, 12 insertions(+), 12 deletions(-) delete mode 100644 spec/latest/.htaccess diff --git a/_redirects b/_redirects index dde88850..f4592c24 100644 --- a/_redirects +++ b/_redirects @@ -1,3 +1,15 @@ /playground-dev /playground 302 /contexts/schema.org.jsonld http://schema.org/ 301 + +/spec/latest/json-ld-syntax https://www.w3.org/TR/json-ld/ 301 +/spec/latest/json-ld-syntax/ https://www.w3.org/TR/json-ld/ 301 + +/spec/latest/json-ld/* https://www.w3.org/TR/json-ld/:splat 301 +/spec/latest/json-ld-api/* https://www.w3.org/TR/json-ld-api/:splat 301 +/spec/latest/json-ld-framing/* https://www.w3.org/TR/json-ld-framing/:splat 301 + +/spec/latest/rdf-graph-normalization https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/ 307 +/spec/latest/rdf-graph-normalization/* https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/:splat 307 +/spec/latest/rdf-dataset-normalization/* https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/:splat 307 +/spec/latest/rdf-dataset-canonicalization/* https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/:splat 307 diff --git a/spec/latest/.htaccess b/spec/latest/.htaccess deleted file mode 100644 index af6788fc..00000000 --- a/spec/latest/.htaccess +++ /dev/null @@ -1,12 +0,0 @@ -RewriteEngine On - -RewriteBase /spec/latest/ -RewriteRule ^json-ld-syntax(.*) json-ld$1 [R=301,NC,L] - -RewriteRule ^json-ld/(.*) https://www.w3.org/TR/json-ld/$1 [R=301,NC,L] -RewriteRule ^json-ld-api/(.*) https://www.w3.org/TR/json-ld-api/$1 [R=301,NC,L] -RewriteRule ^json-ld-framing/(.*) https://www.w3.org/TR/json-ld-framing/$1 [R=301,NC,L] - -RewriteRule ^rdf-graph-normalization(.*) https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/$1 [R=307,NC,L] -RewriteRule ^rdf-dataset-normalization/(.*) https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/$1 [R=307,NC,L] -RewriteRule ^rdf-dataset-canonicalization/(.*) https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/$1 [R=307,NC,L] From 7d3748d8ccb78f4649ff370c262ccb83402f5632 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 09:51:04 -0400 Subject: [PATCH 12/25] Absolutize URLs in 404 page. CSS and images were not loading previously. --- 404.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/404.html b/404.html index b9ba7194..49526412 100644 --- a/404.html +++ b/404.html @@ -16,15 +16,15 @@ - - - + + + - + @@ -53,10 +53,10 @@ From 3c4549014d4c248d8335f5f1c05e66f87cc0abe0 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 11:52:16 -0400 Subject: [PATCH 13/25] Use middleware to handle conneg in test-suite. Sadly, Cloudflare currently only does content negotiation for images. However, the Pages Functions Middleware option is more than sufficient to handle the mapping and loading based on simple Accept header values. NOTE: the current implementation *is not* robust and only handles single value Accept headers. --- functions/test-suite/_middleware.js | 22 +++++++++++++++++ test-suite/.htaccess | 38 ----------------------------- 2 files changed, 22 insertions(+), 38 deletions(-) create mode 100644 functions/test-suite/_middleware.js delete mode 100644 test-suite/.htaccess diff --git a/functions/test-suite/_middleware.js b/functions/test-suite/_middleware.js new file mode 100644 index 00000000..9a6a7c3d --- /dev/null +++ b/functions/test-suite/_middleware.js @@ -0,0 +1,22 @@ +const typeToExt = { + "text/turtle": "ttl", + "application/ld+json": "jsonld" +}; + +export async function onRequest(context) { + try { + const accept = context.request.headers.get('Accept'); + + // if we have a mapping for this extension, send it. Otherwise fall through. + if(Object.keys(typeToExt).indexOf(accept) > -1) { + const ext = typeToExt[accept] || `html`; + const rewrittenUrl = context.request.url + '.' + ext; + const asset = await context.env.ASSETS.fetch(rewrittenUrl); + const response = new Response(asset.body, asset); + return response; + } + return context.next(); + } catch (err) { + return new Response(`${err.message}\n${err.stack}`, { status: 500 }); + } +} diff --git a/test-suite/.htaccess b/test-suite/.htaccess deleted file mode 100644 index 9ca4fb57..00000000 --- a/test-suite/.htaccess +++ /dev/null @@ -1,38 +0,0 @@ - - ForceType application/ld+json - SetHandler default_handler - Header set Access-Control-Allow-Origin "*" - - -# Turn off MultiViews -Options -MultiViews - -# Directive to ensure *.ttl and .jsonld files served appropriately -AddType text/turtle .ttl -AddType application/ld+json .jsonld -AddType application/n-quads .nq - -# Rewrite engine setup -RewriteEngine On -RewriteBase /test-suite - -# Rewrite rule to serve HTML content from the vocabulary URI if requested -RewriteCond %{HTTP_ACCEPT} !application/rdf\+xml.*(text/html|application/xhtml\+xml) -RewriteCond %{HTTP_ACCEPT} text/html [OR] -RewriteCond %{HTTP_ACCEPT} application/xhtml\+xml [OR] -RewriteCond %{HTTP_USER_AGENT} ^Mozilla/.* -RewriteRule ^vocab$ vocab.html [R=303] - -# Rewrite rule to serve Turtle content from the vocabulary URI if requested -RewriteCond %{HTTP_ACCEPT} text/turtle -RewriteRule ^vocab$ vocab.ttl [R=303] - -# Rewrite rule to serve JSON-LD content from the vocabulary URI if requested -RewriteCond %{HTTP_ACCEPT} application/ld+json -RewriteRule ^vocab$ vocab.jsonld [R=303] - -# Choose the default response -# --------------------------- - -# Rewrite rule to serve the HTML content from the vocabulary URI by default -RewriteRule ^vocab$ vocab.html [R=303] From 214890b531aa80e0bb2da53fdd0602e2fe62e790 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 13:59:38 -0400 Subject: [PATCH 14/25] Parse and sort accept headers; pick best q. This commit uses code generated by a Google AI Overview result. They cite no sources and claim no license. However, it is exactly what I was looking for with that search. --- functions/test-suite/_middleware.js | 37 ++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/functions/test-suite/_middleware.js b/functions/test-suite/_middleware.js index 9a6a7c3d..bc2db3b8 100644 --- a/functions/test-suite/_middleware.js +++ b/functions/test-suite/_middleware.js @@ -1,3 +1,37 @@ +function parseAcceptHeader(acceptHeader) { + // generated by Google AI "parse accept header javascript" + if (!acceptHeader) { + return []; + } + + return acceptHeader.split(',') + .map(item => item.trim()) + .map(item => { + const parts = item.split(';'); + const value = parts[0].trim(); + let quality = 1; + + if (parts.length > 1) { + const q = parts[1].trim(); + if (q.startsWith('q=')) { + quality = parseFloat(q.substring(2)); + } + } + + return { value, quality }; + }) + .sort((a, b) => b.quality - a.quality); + // From: + // text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8 + // Expected output: + // [ + // { value: 'text/html', quality: 1 }, + // { value: 'application/xhtml+xml', quality: 1 }, + // { value: 'application/xml', quality: 0.9 }, + // { value: '*/*', quality: 0.8 } + // ] +} + const typeToExt = { "text/turtle": "ttl", "application/ld+json": "jsonld" @@ -5,7 +39,8 @@ const typeToExt = { export async function onRequest(context) { try { - const accept = context.request.headers.get('Accept'); + const parsedAccept = parseAcceptHeader(context.request.headers.get('Accept')); + const accept = parsedAccept[0].value; // if we have a mapping for this extension, send it. Otherwise fall through. if(Object.keys(typeToExt).indexOf(accept) > -1) { From 4e8b12f3be76818919c844969f4e26e8e6099896 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 14:26:30 -0400 Subject: [PATCH 15/25] Migrate test-suite/tests/ redirs & headers. --- _headers | 18 ++++++++++++++++++ _redirects | 5 +++++ test-suite/tests/.htaccess | 30 ------------------------------ 3 files changed, 23 insertions(+), 30 deletions(-) delete mode 100644 test-suite/tests/.htaccess diff --git a/_headers b/_headers index 418281ad..5764fc51 100644 --- a/_headers +++ b/_headers @@ -10,3 +10,21 @@ /contexts/recipe Content-Type: application/ld+json Access-Control-Allow-Origin: "*" + +/test-suite/tests/*.jldt + Content-Type: application/jldTest+json +/test-suite/tests/*.jldte + Content-Type: application/jldTest + +# Tests 0009-0011 Add link header +/test-suite/tests/remote-doc-0009-in.jsonld + Link: '; rel="http://www.w3.org/ns/json-ld#context"' +/test-suite/tests/remote-doc-0010-in.json + Link: '; rel="http://www.w3.org/ns/json-ld#context"' +/test-suite/tests/remote-doc-0011-in.jldt + Link: '; rel="http://www.w3.org/ns/json-ld#context"' + +# Test 00012 adds multiple link headers +/test-suite/tests/remote-doc-0012-in.json + Link: '; rel="http://www.w3.org/ns/json-ld#context"' + Link: '; rel="http://www.w3.org/ns/json-ld#context"' diff --git a/_redirects b/_redirects index f4592c24..41d47b02 100644 --- a/_redirects +++ b/_redirects @@ -5,6 +5,11 @@ /spec/latest/json-ld-syntax https://www.w3.org/TR/json-ld/ 301 /spec/latest/json-ld-syntax/ https://www.w3.org/TR/json-ld/ 301 +# Tests 0005-0007, status redirect to 0001 +/test-suite/remote-doc-0005-in.jsonld /test-suite/tests/remote-doc-0001-in.jsonld 301 +/test-suite/remote-doc-0006-in.jsonld /test-suite/tests/remote-doc-0001-in.jsonld 303 +/test-suite/remote-doc-0007-in.jsonld /test-suite/tests/remote-doc-0001-in.jsonld 307 + /spec/latest/json-ld/* https://www.w3.org/TR/json-ld/:splat 301 /spec/latest/json-ld-api/* https://www.w3.org/TR/json-ld-api/:splat 301 /spec/latest/json-ld-framing/* https://www.w3.org/TR/json-ld-framing/:splat 301 diff --git a/test-suite/tests/.htaccess b/test-suite/tests/.htaccess deleted file mode 100644 index 45a04ae8..00000000 --- a/test-suite/tests/.htaccess +++ /dev/null @@ -1,30 +0,0 @@ -# Special rules for document loader tests -# Rewrite engine setup -RewriteEngine On -RewriteBase /test-suite - -# Add directive for test types -AddType application/jldTest+json .jldt -AddType application/jldTest .jldte - -# Tests 0005-0007, status redirect to 0001 -RewriteRule ^remote-doc-0005-in.jsonld$ tests/remote-doc-0001-in.jsonld [R=301] -RewriteRule ^remote-doc-0006-in.jsonld$ tests/remote-doc-0001-in.jsonld [R=303] -RewriteRule ^remote-doc-0007-in.jsonld$ tests/remote-doc-0001-in.jsonld [R=307] - -# Tests 0009-0011 Add link header - - Header set Link '; rel="http://www.w3.org/ns/json-ld#context"' - - - Header set Link '; rel="http://www.w3.org/ns/json-ld#context"' - - - Header set Link '; rel="http://www.w3.org/ns/json-ld#context"' - - -# Test 00012 adds multiple link headers - - Header set Link '; rel="http://www.w3.org/ns/json-ld#context"' - Header append Link '; rel="http://www.w3.org/ns/json-ld#context"' - From 2b262ec2cd1ad21307f10a37216a130da7478149 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 14:29:39 -0400 Subject: [PATCH 16/25] Remove utils/; No longer needed. --- .eleventy.js | 1 - utils/.htaccess | 5 ---- utils/README | 13 --------- utils/git.php | 74 ------------------------------------------------- 4 files changed, 93 deletions(-) delete mode 100644 utils/.htaccess delete mode 100644 utils/README delete mode 100644 utils/git.php diff --git a/.eleventy.js b/.eleventy.js index 7a7dcf34..56950b54 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -37,7 +37,6 @@ module.exports = function(eleventyConfig) { } eleventyConfig.addPassthroughCopy('static'); eleventyConfig.addPassthroughCopy('test-suite'); - eleventyConfig.addPassthroughCopy('utils'); eleventyConfig.ignores.add('CONTRIBUTING.md'); eleventyConfig.ignores.add('LICENSE.md'); eleventyConfig.ignores.add('README.md'); diff --git a/utils/.htaccess b/utils/.htaccess deleted file mode 100644 index d5d0d53b..00000000 --- a/utils/.htaccess +++ /dev/null @@ -1,5 +0,0 @@ - - order allow,deny - deny from all - - diff --git a/utils/README b/utils/README deleted file mode 100644 index 8bb70691..00000000 --- a/utils/README +++ /dev/null @@ -1,13 +0,0 @@ -Usage ------ - -In order to use the git.php file, you must create a file called -remote-update-token.txt and place a value in there. You must then call -the git.php file with a URL parameter named 'token' set to the value in -the file. For example: - -https://json-ld.org/utils/git.php?token=7384724849 - -While this is not a fool-proof security solution, it'll be good enough -for now. Updates are throttled, even in the event of a DDoS, the update -rate is once every 5 seconds. diff --git a/utils/git.php b/utils/git.php deleted file mode 100644 index 97296748..00000000 --- a/utils/git.php +++ /dev/null @@ -1,74 +0,0 @@ - From 3146f22742eee646b28ec4c09b1052feef48ec05 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Tue, 1 Apr 2025 16:18:43 -0400 Subject: [PATCH 17/25] Switch to type: module. --- .eleventy.js | 2 +- package.json | 1 + requirements/index.11tydata.js | 9 ++++++--- spec/index.11tydata.js | 17 ++++++++++------- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/.eleventy.js b/.eleventy.js index 56950b54..2ce0822f 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -12,7 +12,7 @@ const drafts = [ 'latest' ]; -module.exports = function(eleventyConfig) { +export default async function(eleventyConfig) { eleventyConfig.addPassthroughCopy('404.html'); eleventyConfig.addPassthroughCopy('.htaccess'); eleventyConfig.addPassthroughCopy('LICENSE.md'); diff --git a/package.json b/package.json index e3797eb5..77bbf783 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "json-ld.org", "private": true, "description": "json-ld.org homepage", + "type": "module", "scripts": { "build": "eleventy", "pages": "wrangler pages dev _site/", diff --git a/requirements/index.11tydata.js b/requirements/index.11tydata.js index 5d9597f6..a3650db6 100644 --- a/requirements/index.11tydata.js +++ b/requirements/index.11tydata.js @@ -1,5 +1,8 @@ -const fs = require('node:fs/promises'); -const path = require('node:path'); +import { fileURLToPath } from 'url'; +import fs from 'node:fs/promises'; +import path from 'node:path'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const specStatuses = ['ED']; @@ -35,7 +38,7 @@ const specs = [ 'requirements' ]; -module.exports = async function() { +export default async function() { return { specs: Object.fromEntries(await Promise.all(specs.map(async spec => { return [spec, await getDrafts(spec)]; diff --git a/spec/index.11tydata.js b/spec/index.11tydata.js index 83967fda..a54ae471 100644 --- a/spec/index.11tydata.js +++ b/spec/index.11tydata.js @@ -1,5 +1,8 @@ -const fs = require('node:fs/promises'); -const path = require('node:path'); +import { fileURLToPath } from 'url'; +import fs from 'node:fs/promises'; +import path from 'node:path'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const specStatuses = ['ED', 'FCGS', 'WD', 'CR', 'PR', 'REC'/*, 'CG-FINAL'*/]; @@ -33,14 +36,14 @@ async function getDrafts(spec) { const specs = [ 'json-ld', - 'json-ld-syntax', - 'json-ld-api', - 'json-ld-api-best-practices', - 'json-ld-framing', + 'json-ld-syntax', + 'json-ld-api', + 'json-ld-api-best-practices', + 'json-ld-framing', 'json-ld-rdf' ]; -module.exports = async function() { +export default async function() { return { specs: Object.fromEntries(await Promise.all(specs.map(async spec => { return [spec, await getDrafts(spec)]; From 4881cf3a77cb811f0a89cb74a390bdc1cbd7b3a3 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Tue, 1 Apr 2025 16:58:58 -0400 Subject: [PATCH 18/25] Add initial test-redirects.js script. Not sure we need to keep this around...but I suppose it could be handy all the same. --- test-redirects.js | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 test-redirects.js diff --git a/test-redirects.js b/test-redirects.js new file mode 100644 index 00000000..bbd92ea8 --- /dev/null +++ b/test-redirects.js @@ -0,0 +1,78 @@ +import assert from 'node:assert/strict'; + +const baseUri = 'http://localhost:8788'; + +(async () => { + // test json-ld media type + const url = `${baseUri}/contexts/event.jsonld`; + const resp = await fetch(url); + assert(resp.headers.get('Content-Type') === 'application/ld+json', + `Content-Type for ${url} should be application/ld+json.`); +})(); + +(async () => { + // test that /playground-dev redirects to /playground + const url = `${baseUri}/playground-dev`; + const resp = await fetch(url, {redirect: 'manual'}); + assert(resp.status === 302, + `Should be a 302 redirect.`); + const location = resp.headers.get('Location'); + assert(location === '/playground', + `Old /playground-dev should redirect to /playground`); +})(); + +(async () => { + // test json-ld media type on URLs without extensions + const urls = [ + `${baseUri}/contexts/event`, + `${baseUri}/contexts/person`, + `${baseUri}/contexts/place`, + `${baseUri}/contexts/recipe`, + ]; + Promise.all(urls.map(async (url) => { + const resp = await fetch(url, {redirect: 'manual'}); + const contentType = resp.headers.get('Content-Type'); + assert(contentType === 'application/ld+json', + `Content-Type for ${url} should be application/ld+json; got ${contentType}.`); + const cors = resp.headers.get('Access-Control-Allow-Origin'); + assert(cors === '"*"', + `Header 'Access-Control-Allow-Origin' should be '*'; got ${cors}.`); + })); +})(); + +(async () => { + // test json-ld media type + const urls = [ + `${baseUri}/contexts/event`, + `${baseUri}/contexts/person`, + `${baseUri}/contexts/place`, + `${baseUri}/contexts/recipe`, + ]; + Promise.all(urls.map(async (url) => { + const resp = await fetch(url, {redirect: 'manual'}); + const contentType = resp.headers.get('Content-Type'); + assert(contentType === 'application/ld+json', + `Content-Type for ${url} should be application/ld+json; got ${contentType}.`); + const cors = resp.headers.get('Access-Control-Allow-Origin'); + assert(cors === '"*"', + `Header 'Access-Control-Allow-Origin' should be '*'; got ${cors}.`); + })); +})(); + +(async () => { + // test media type for `*.jldte` + const url = `${baseUri}/test-suite/tests/remote-doc-0003-in.jldt`; + const resp = await fetch(url); + const contentType = resp.headers.get('Content-Type'); + assert(contentType === 'application/jldTest+json', + `Content-Type for ${url} should be application/jldTest+json; got ${contentType}.`); +})(); + +(async () => { + // test media type for `*.jldte` + const url = `${baseUri}/test-suite/tests/remote-doc-0004-in.jldte`; + const resp = await fetch(url); + const contentType = resp.headers.get('Content-Type'); + assert(contentType === 'application/jldTest', + `Content-Type for ${url} should be application/jldTest; got ${contentType}.`); +})(); From 48a1e8560d1370b6a58c2ee98f198b6598966923 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 10:27:05 -0400 Subject: [PATCH 19/25] Test Link headers via _headers. --- test-redirects.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test-redirects.js b/test-redirects.js index bbd92ea8..e3171f4f 100644 --- a/test-redirects.js +++ b/test-redirects.js @@ -76,3 +76,26 @@ const baseUri = 'http://localhost:8788'; assert(contentType === 'application/jldTest', `Content-Type for ${url} should be application/jldTest; got ${contentType}.`); })(); + +(async () => { + // test link headers + const urlsToLinkHeaderValues = { + '/test-suite/tests/remote-doc-0009-in.jsonld': + `; rel="http://www.w3.org/ns/json-ld#context"`, + '/test-suite/tests/remote-doc-0010-in.json': + `; rel="http://www.w3.org/ns/json-ld#context"`, + '/test-suite/tests/remote-doc-0011-in.jldt': + `; rel="http://www.w3.org/ns/json-ld#context"`, + '/test-suite/tests/remote-doc-0012-in.json': + `; rel="http://www.w3.org/ns/json-ld#context", ; rel="http://www.w3.org/ns/json-ld#context"` + }; + Promise.all(Object.entries(urlsToLinkHeaderValues) + .map(async ([absoultePath, intendedHeaderValue]) => { + const url = `${baseUri}${absoultePath}`; + const resp = await fetch(url); + const actualLinkValue = resp.headers.get('Link'); + assert(actualLinkValue === intendedHeaderValue, + `Link header for ${url} should be ${intendedHeaderValue}; got ${actualLinkValue}.`); + }) + ); +})(); From 1cf54e7cfb8911dfbb897faf4e409488b65f8a82 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 10:27:43 -0400 Subject: [PATCH 20/25] Optimize _headers order and format. --- _headers | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/_headers b/_headers index 5764fc51..8cede675 100644 --- a/_headers +++ b/_headers @@ -11,20 +11,20 @@ Content-Type: application/ld+json Access-Control-Allow-Origin: "*" -/test-suite/tests/*.jldt - Content-Type: application/jldTest+json -/test-suite/tests/*.jldte - Content-Type: application/jldTest - # Tests 0009-0011 Add link header /test-suite/tests/remote-doc-0009-in.jsonld - Link: '; rel="http://www.w3.org/ns/json-ld#context"' + Link: ; rel="http://www.w3.org/ns/json-ld#context" /test-suite/tests/remote-doc-0010-in.json - Link: '; rel="http://www.w3.org/ns/json-ld#context"' + Link: ; rel="http://www.w3.org/ns/json-ld#context" /test-suite/tests/remote-doc-0011-in.jldt - Link: '; rel="http://www.w3.org/ns/json-ld#context"' + Link: ; rel="http://www.w3.org/ns/json-ld#context" # Test 00012 adds multiple link headers /test-suite/tests/remote-doc-0012-in.json - Link: '; rel="http://www.w3.org/ns/json-ld#context"' - Link: '; rel="http://www.w3.org/ns/json-ld#context"' + Link: ; rel="http://www.w3.org/ns/json-ld#context" + Link: ; rel="http://www.w3.org/ns/json-ld#context" + +/test-suite/tests/*.jldt + Content-Type: application/jldTest+json +/test-suite/tests/*.jldte + Content-Type: application/jldTest From aeda593af0661693f2520dc2ec67c79c11b0f3db Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 10:29:13 -0400 Subject: [PATCH 21/25] Reorder test-redirects.js; group test types. --- test-redirects.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/test-redirects.js b/test-redirects.js index e3171f4f..686d3250 100644 --- a/test-redirects.js +++ b/test-redirects.js @@ -2,6 +2,7 @@ import assert from 'node:assert/strict'; const baseUri = 'http://localhost:8788'; +// Test _headers (async () => { // test json-ld media type const url = `${baseUri}/contexts/event.jsonld`; @@ -10,17 +11,6 @@ const baseUri = 'http://localhost:8788'; `Content-Type for ${url} should be application/ld+json.`); })(); -(async () => { - // test that /playground-dev redirects to /playground - const url = `${baseUri}/playground-dev`; - const resp = await fetch(url, {redirect: 'manual'}); - assert(resp.status === 302, - `Should be a 302 redirect.`); - const location = resp.headers.get('Location'); - assert(location === '/playground', - `Old /playground-dev should redirect to /playground`); -})(); - (async () => { // test json-ld media type on URLs without extensions const urls = [ @@ -99,3 +89,15 @@ const baseUri = 'http://localhost:8788'; }) ); })(); + +// Test _redirects +(async () => { + // test that /playground-dev redirects to /playground + const url = `${baseUri}/playground-dev`; + const resp = await fetch(url, {redirect: 'manual'}); + assert(resp.status === 302, + `Should be a 302 redirect.`); + const location = resp.headers.get('Location'); + assert(location === '/playground', + `Old /playground-dev should redirect to /playground`); +})(); From b1403b857aad4e41e2521756e91931e2d6b52922 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 11:00:14 -0400 Subject: [PATCH 22/25] Test all redirects in _redirects. --- test-redirects.js | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/test-redirects.js b/test-redirects.js index 686d3250..f0775ed0 100644 --- a/test-redirects.js +++ b/test-redirects.js @@ -1,4 +1,5 @@ import assert from 'node:assert/strict'; +import fs from 'node:fs/promises'; const baseUri = 'http://localhost:8788'; @@ -92,12 +93,24 @@ const baseUri = 'http://localhost:8788'; // Test _redirects (async () => { - // test that /playground-dev redirects to /playground - const url = `${baseUri}/playground-dev`; - const resp = await fetch(url, {redirect: 'manual'}); - assert(resp.status === 302, - `Should be a 302 redirect.`); - const location = resp.headers.get('Location'); - assert(location === '/playground', - `Old /playground-dev should redirect to /playground`); + const _redirects = await fs.readFile('./_redirects', 'utf-8'); + Promise.all(_redirects.split('\n') + .filter((v) => (v[0] !== '#') ? v : null) + .map(async (line) => { + let [source, destination, code] = line.split(/\s/); + if(source.endsWith('*')) { + // remove * + source = source.slice(0, source.length - 1); + // remove :splat + destination = destination.slice(0, destination.length - 6); + } + const url = `${baseUri}${source}`; + const resp = await fetch(url, {redirect: 'manual'}); + assert(resp.status === code || 302, + `Should be a 302 redirect.`); + const location = resp.headers.get('Location'); + assert(location === destination, + `Old ${source} should redirect to ${destination}, got ${location}`); + }) + ); })(); From 4b359c2125fb41b008cc7335a79a4a124c047820 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 11:07:16 -0400 Subject: [PATCH 23/25] Optimize redirect order; https for schema.org. --- _redirects | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_redirects b/_redirects index 41d47b02..719487eb 100644 --- a/_redirects +++ b/_redirects @@ -1,6 +1,6 @@ /playground-dev /playground 302 -/contexts/schema.org.jsonld http://schema.org/ 301 +/contexts/schema.org.jsonld https://schema.org/ 301 /spec/latest/json-ld-syntax https://www.w3.org/TR/json-ld/ 301 /spec/latest/json-ld-syntax/ https://www.w3.org/TR/json-ld/ 301 @@ -10,11 +10,11 @@ /test-suite/remote-doc-0006-in.jsonld /test-suite/tests/remote-doc-0001-in.jsonld 303 /test-suite/remote-doc-0007-in.jsonld /test-suite/tests/remote-doc-0001-in.jsonld 307 -/spec/latest/json-ld/* https://www.w3.org/TR/json-ld/:splat 301 -/spec/latest/json-ld-api/* https://www.w3.org/TR/json-ld-api/:splat 301 -/spec/latest/json-ld-framing/* https://www.w3.org/TR/json-ld-framing/:splat 301 - /spec/latest/rdf-graph-normalization https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/ 307 /spec/latest/rdf-graph-normalization/* https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/:splat 307 /spec/latest/rdf-dataset-normalization/* https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/:splat 307 /spec/latest/rdf-dataset-canonicalization/* https://w3c-ccg.github.io/rdf-dataset-canonicalization/spec/:splat 307 + +/spec/latest/json-ld/* https://www.w3.org/TR/json-ld/:splat 301 +/spec/latest/json-ld-api/* https://www.w3.org/TR/json-ld-api/:splat 301 +/spec/latest/json-ld-framing/* https://www.w3.org/TR/json-ld-framing/:splat 301 From c0002da40b0c89e291ad5120691cca4fd1885e91 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 11:07:33 -0400 Subject: [PATCH 24/25] Set wrangler compatibility date. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 77bbf783..f013ec84 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "build": "eleventy", - "pages": "wrangler pages dev _site/", + "pages": "wrangler pages dev _site/ --compatibility-date=2025-04-02", "serve": "eleventy --serve", "watch": "eleventy --watch", "dev": "wrangler pages dev _site --compatibility-date=2024-04-27 --live-reload --port 8788", From 33d5dcf683069ad377bab651f39c8534fbf63fa9 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 11:19:52 -0400 Subject: [PATCH 25/25] Remove `eleventy --serve`; promote using `run pages`. --- README.md | 6 ++---- package.json | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1b7e0d93..cd9a3bcc 100644 --- a/README.md +++ b/README.md @@ -74,12 +74,10 @@ To develop this website locally: ```sh # install dependencies npm i -# to rebuild on changes and run a server: -npm run serve -# to rebuild on changes: -npm run watch # to just build the static files to `_site/` npm run build +# to rebuild the files on changes +npm run watch # to serve `_site/` with Cloudflare Pages feature support npm run pages # visit http://localhost:8788/ ``` diff --git a/package.json b/package.json index f013ec84..a1e31927 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "scripts": { "build": "eleventy", "pages": "wrangler pages dev _site/ --compatibility-date=2025-04-02", - "serve": "eleventy --serve", "watch": "eleventy --watch", "dev": "wrangler pages dev _site --compatibility-date=2024-04-27 --live-reload --port 8788", "test": "echo \"Error: no test specified\" && exit 1"