From 19883af56fb78b88239b1b4e1e4a944edc988b94 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Sat, 24 Feb 2024 00:04:36 -0500 Subject: [PATCH 01/33] Remove empty file. --- earl.jsonld | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 earl.jsonld diff --git a/earl.jsonld b/earl.jsonld deleted file mode 100644 index e69de29bb..000000000 From e95d49b006f158682c2c756539ce9464cf17dffc Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Fri, 23 Feb 2024 21:18:01 -0500 Subject: [PATCH 02/33] Convert to Eleventy. - Copy and ignore files as needed. - Comment out old `prettify.css` usage. - Move `learn.html` to `learn/index.html` and update links. This could break external links, but is aligned with the pattern of other files and dirs. Eleventy will put it in `learn/` by default either way without an override. - `specs/`, `primer/`, and `requirements/`: - Generate sub-dir listing data with JS. - Switch from PHP to LiquidJS. --- .eleventy.js | 52 ++++++++++++ .gitignore | 1 + images/index.html | 4 +- index.html | 4 +- learn.html => learn/index.html | 18 ++--- package.json | 15 ++++ playground/1.0/index.html | 2 +- playground/dev/index.html | 2 +- playground/index.html | 2 +- primer/{index.php => index.html} | 120 +++++++++++++--------------- requirements/index.11tydata.js | 44 +++++++++++ requirements/index.html | 123 +++++++++++++++++++++++++++++ requirements/index.php | 131 ------------------------------- spec/index.11tydata.js | 49 ++++++++++++ spec/{index.php => index.html} | 99 ++++++----------------- test-suite/index.html | 2 +- test-suite/vocab.html | 2 +- test-suite/vocab_template.haml | 2 +- 18 files changed, 383 insertions(+), 289 deletions(-) create mode 100644 .eleventy.js rename learn.html => learn/index.html (92%) create mode 100644 package.json rename primer/{index.php => index.html} (54%) create mode 100644 requirements/index.11tydata.js create mode 100644 requirements/index.html delete mode 100644 requirements/index.php create mode 100644 spec/index.11tydata.js rename spec/{index.php => index.html} (82%) diff --git a/.eleventy.js b/.eleventy.js new file mode 100644 index 000000000..bb5a141dc --- /dev/null +++ b/.eleventy.js @@ -0,0 +1,52 @@ +const drafts = [ + 'CG-FINAL', + 'CR', + 'ED', + 'FCGS', + 'PR', + 'REC', + 'WD', + 'latest' +]; + +module.exports = function(eleventyConfig) { + eleventyConfig.addPassthroughCopy('.htaccess'); + eleventyConfig.addPassthroughCopy('LICENSE.md'); + eleventyConfig.addPassthroughCopy('benchmarks/**/*.{jsonld,nq,md}'); + eleventyConfig.addPassthroughCopy('contexts/**/*.{htaccess,html,jsonld}'); + eleventyConfig.addPassthroughCopy('contexts/{event,person,place,recipe,remote-context}'); + eleventyConfig.addPassthroughCopy('examples/**/*.{html,ttl,txt,json}'); + eleventyConfig.addPassthroughCopy('favicon.ico'); + eleventyConfig.addPassthroughCopy('fonts'); + eleventyConfig.addPassthroughCopy('images/**/*.{htaccess,png,svg,xcf}'); + eleventyConfig.addPassthroughCopy('ns/**/*.{html,jsonld}'); + eleventyConfig.addPassthroughCopy('playground/**/*.{css,php,js}'); + eleventyConfig.addPassthroughCopy('presentations'); + eleventyConfig.addPassthroughCopy('schemas/**/*.json'); + eleventyConfig.addPassthroughCopy('site.css'); + eleventyConfig.addPassthroughCopy('spec/LICENSE.md'); + for(const draft of drafts) { + eleventyConfig.addPassthroughCopy(`spec/${draft}`); + } + eleventyConfig.addPassthroughCopy('static'); + eleventyConfig.addPassthroughCopy('test-suite'); + eleventyConfig.addPassthroughCopy('utils'); + eleventyConfig.ignores.add('CONTRIBUTING.md'); + eleventyConfig.ignores.add('LICENSE.md'); + eleventyConfig.ignores.add('README.rst'); + eleventyConfig.ignores.add('benchmarks/README.md'); + eleventyConfig.ignores.add('contexts/person.html'); + eleventyConfig.ignores.add('examples'); + eleventyConfig.ignores.add('images/README.md'); + eleventyConfig.ignores.add('minutes/**/*'); + eleventyConfig.ignores.add('ns/json-ld.html'); + eleventyConfig.ignores.add('playground/dev/README.md'); + eleventyConfig.ignores.add('presentations'); + eleventyConfig.ignores.add('scripts'); + eleventyConfig.ignores.add('spec/tools'); + eleventyConfig.ignores.add('spec/LICENSE.md'); + for(const draft of drafts) { + eleventyConfig.ignores.add(`spec/${draft}`); + } + eleventyConfig.ignores.add('test-suite'); +}; diff --git a/.gitignore b/.gitignore index edfb95873..07504bcf6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ .DS_Store node_modules playground/jsonld.js +_site diff --git a/images/index.html b/images/index.html index 4ad5c9d9b..00b88149e 100644 --- a/images/index.html +++ b/images/index.html @@ -19,7 +19,7 @@ - + @@ -52,7 +52,7 @@ Playground
  • - Documentation + Documentation
  • Developers
  • - Documentation + Documentation
  • Developers
  • -
  • Branding
  • +
  • Branding
  • @@ -145,6 +145,6 @@

    Blog Posts

    - + diff --git a/package.json b/package.json new file mode 100644 index 000000000..b29747e02 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "json-ld.org", + "private": true, + "description": "json-ld.org homepage", + "scripts": { + "build": "npx @11ty/eleventy", + "serve": "npx @11ty/eleventy --serve", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "", + "devDependencies": { + "@11ty/eleventy": "^2.0.1" + } +} diff --git a/playground/1.0/index.html b/playground/1.0/index.html index 9e9f219de..be75e45d3 100644 --- a/playground/1.0/index.html +++ b/playground/1.0/index.html @@ -44,7 +44,7 @@ Playground
  • - Documentation + Documentation
  • Developers
  • - Documentation + Documentation
  • Developers
  • - Documentation + Documentation
  • Developers
  • - Documentation + Documentation
  • Developers
  • - Documentation + Documentation
  • Developers
  • - + Documentation diff --git a/test-suite/vocab_template.haml b/test-suite/vocab_template.haml index bf5c534d3..9aeb27b43 100644 --- a/test-suite/vocab_template.haml +++ b/test-suite/vocab_template.haml @@ -33,7 +33,7 @@ %span.icon-beer Playground %li - %a{:href => "../learn.html"} + %a{:href => "../learn/"} %span.icon-book Documentation %li From ba19a5241f4716465812754ec56f362966c3ce1b Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Thu, 25 Apr 2024 21:03:23 -0400 Subject: [PATCH 03/33] Use installed eleventy. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b29747e02..e3c69419a 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "private": true, "description": "json-ld.org homepage", "scripts": { - "build": "npx @11ty/eleventy", - "serve": "npx @11ty/eleventy --serve", + "build": "eleventy", + "serve": "eleventy --serve", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", From 386eb142d4b8d731dbe36a54288b60ee0690d194 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Thu, 25 Apr 2024 21:03:38 -0400 Subject: [PATCH 04/33] Remove unused fields. --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index e3c69419a..977106e8a 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,6 @@ "serve": "eleventy --serve", "test": "echo \"Error: no test specified\" && exit 1" }, - "author": "", - "license": "", "devDependencies": { "@11ty/eleventy": "^2.0.1" } From b0fa2a874f0204eb787ef5d13c28ea5125f2ecd1 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Tue, 30 Apr 2024 21:22:42 -0400 Subject: [PATCH 05/33] Convert README to markdown. - Convert README from reStructuredText to Markdown. - The reStructuredText format still works, and was a fine choice back in 2010(!) but Markdown is more common for READMEs like this today. --- .eleventy.js | 2 +- README.rst => README.md | 41 +++++++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 19 deletions(-) rename README.rst => README.md (58%) diff --git a/.eleventy.js b/.eleventy.js index bb5a141dc..60586abd6 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -33,7 +33,7 @@ module.exports = function(eleventyConfig) { eleventyConfig.addPassthroughCopy('utils'); eleventyConfig.ignores.add('CONTRIBUTING.md'); eleventyConfig.ignores.add('LICENSE.md'); - eleventyConfig.ignores.add('README.rst'); + eleventyConfig.ignores.add('README.md'); eleventyConfig.ignores.add('benchmarks/README.md'); eleventyConfig.ignores.add('contexts/person.html'); eleventyConfig.ignores.add('examples'); diff --git a/README.rst b/README.md similarity index 58% rename from README.rst rename to README.md index c606ad181..110a20f37 100644 --- a/README.rst +++ b/README.md @@ -1,9 +1,12 @@ +json-ld.org +=========== + Introduction ------------ -.. image:: https://badges.gitter.im/json-ld/json-ld.org.svg - :alt: Join the chat at https://gitter.im/json-ld/json-ld.org - :target: https://gitter.im/json-ld/json-ld.org?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge +[![Join the chat at https://gitter.im/json-ld/json-ld.org](https://badges.gitter.im/json-ld/json-ld.org.svg)](https://gitter.im/json-ld/json-ld.org) + +This is the source for the https://json-ld.org/ website. JSON-LD (JavaScript Object Notation for Linking Data) is a lightweight Linked Data format. It is easy for humans to read and write. It is easy for machines @@ -15,7 +18,7 @@ These properties make JSON-LD an ideal Linked Data interchange language for JavaScript environments, Web services, and unstructured databases such as CouchDB and MongoDB. -If you are already using JSON-LD, add yourself to the `list of users`_ in our wiki. +If you are already using JSON-LD, add yourself to the [list of users][] in our wiki. A Simple Example @@ -23,13 +26,15 @@ A Simple Example A simple example of a JSON object with added semantics:: - { - "@context": "https://json-ld.org/contexts/person.jsonld", - "@id": "http://dbpedia.org/resource/John_Lennon", - "name": "John Lennon", - "born": "1940-10-09", - "spouse": "http://dbpedia.org/resource/Cynthia_Lennon" - } +```json +{ + "@context": "https://json-ld.org/contexts/person.jsonld", + "@id": "http://dbpedia.org/resource/John_Lennon", + "name": "John Lennon", + "born": "1940-10-09", + "spouse": "http://dbpedia.org/resource/Cynthia_Lennon" +} +``` The example above describes a person whose name is John Lennon. The difference between regular JSON and JSON-LD is that the JSON-LD object above uniquely @@ -49,15 +54,15 @@ The Specifications If you are a developer, you may be interested in the official JSON-LD W3C specifications: -* `JSON-LD 1.1 - A JSON-based Serialization for Linked Data`_ -* `JSON-LD 1.1 Processing Algorithms and API`_ -* `JSON-LD 1.1 Framing`_ +* [JSON-LD 1.1 - A JSON-based Serialization for Linked Data][] +* [JSON-LD 1.1 Processing Algorithms and API][] +* [JSON-LD 1.1 Framing][] A list of all previous specification drafts is also available. https://json-ld.org/spec/ -.. _list of users: https://github.com/json-ld/json-ld.org/wiki/Users-of-JSON-LD -.. _JSON-LD 1.1 - A JSON-based Serialization for Linked Data: http://www.w3.org/TR/json-ld/ -.. _JSON-LD 1.1 Processing Algorithms and API: http://www.w3.org/TR/json-ld-api/ -.. _JSON-LD 1.1 Framing: http://www.w3.org/TR/json-ld-framing/ +[list of users]: https://github.com/json-ld/json-ld.org/wiki/Users-of-JSON-LD +[JSON-LD 1.1 - A JSON-based Serialization for Linked Data]: http://www.w3.org/TR/json-ld/ +[JSON-LD 1.1 Processing Algorithms and API]: https://www.w3.org/TR/json-ld-api/ +[JSON-LD 1.1 Framing]: https://www.w3.org/TR/json-ld-framing/ From a8a8b0cbf531e05e8358c050a8554a8ede926fa0 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Tue, 30 Apr 2024 23:08:05 -0400 Subject: [PATCH 06/33] Add 404 page. - Add `404.html` for Cloudflare Pages. --- .eleventy.js | 1 + 404.html | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 404.html diff --git a/.eleventy.js b/.eleventy.js index 60586abd6..593c08a29 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -10,6 +10,7 @@ const drafts = [ ]; module.exports = function(eleventyConfig) { + eleventyConfig.addPassthroughCopy('404.html'); eleventyConfig.addPassthroughCopy('.htaccess'); eleventyConfig.addPassthroughCopy('LICENSE.md'); eleventyConfig.addPassthroughCopy('benchmarks/**/*.{jsonld,nq,md}'); diff --git a/404.html b/404.html new file mode 100644 index 000000000..b9ba71943 --- /dev/null +++ b/404.html @@ -0,0 +1,100 @@ + + + + JSON-LD - JSON for Linking Data + + + + + + + + + + + + + + + + + + + + + + +
    +

    Page not found.

    +
    + + + + + From d36603896edd058a28b1b1d32f976f718341cb29 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Tue, 30 Apr 2024 21:31:18 -0400 Subject: [PATCH 07/33] Ignore .backup files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 07504bcf6..7f0a39a1c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *~ +*.backup *.sw[op] .DS_Store node_modules From eac8e81e2f7b7b649e9af013a824ba4e96c63d70 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Tue, 30 Apr 2024 21:52:52 -0400 Subject: [PATCH 08/33] Use Cloudflare Pages Fuction for playground proxy.. - Remove PHP proxy code. - Move proxy URL to /playground/proxy. - Use eleventy@3 alpha for `onRequset` dev server support. - Add Eleventy dev server `onRequest` proxy to local wrangler server proxy. Due to current limited API, emulate a basic playground request. - Reimplement proxy as a Cloudflare Pages Function. - Basic proxy designed for limited use and abuse. - Add various checks to limit useful scope. - Update README. - Ignore .wrangler. --- .eleventy.js | 39 ++++++++++++++++++++ .gitignore | 1 + README.md | 34 ++++++++++++++++-- functions/playground/proxy.js | 68 +++++++++++++++++++++++++++++++++++ package.json | 4 ++- playground/1.0/playground.js | 2 +- playground/1.0/proxy.php | 53 --------------------------- playground/playground.js | 2 +- playground/proxy.php | 53 --------------------------- 9 files changed, 145 insertions(+), 111 deletions(-) create mode 100644 functions/playground/proxy.js delete mode 100644 playground/1.0/proxy.php delete mode 100644 playground/proxy.php diff --git a/.eleventy.js b/.eleventy.js index 593c08a29..096e6fb9a 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -1,3 +1,6 @@ +// development host for playground proxy +const PLAYGROUND_PROXY_HOST = 'http://localhost:8788'; + const drafts = [ 'CG-FINAL', 'CR', @@ -19,6 +22,7 @@ module.exports = function(eleventyConfig) { eleventyConfig.addPassthroughCopy('examples/**/*.{html,ttl,txt,json}'); eleventyConfig.addPassthroughCopy('favicon.ico'); eleventyConfig.addPassthroughCopy('fonts'); + eleventyConfig.addPassthroughCopy('functions/**/*.js'); eleventyConfig.addPassthroughCopy('images/**/*.{htaccess,png,svg,xcf}'); eleventyConfig.addPassthroughCopy('ns/**/*.{html,jsonld}'); eleventyConfig.addPassthroughCopy('playground/**/*.{css,php,js}'); @@ -50,4 +54,39 @@ module.exports = function(eleventyConfig) { eleventyConfig.ignores.add(`spec/${draft}`); } eleventyConfig.ignores.add('test-suite'); + + // setup development proxy to cloudflare pages function server + if(process.env.ELEVENTY_RUN_MODE === 'serve') { + eleventyConfig.setServerOptions({ + onRequest: { + '/playground/proxy': playgroundProxy + } + }); + } }; + +// proxy to worker proxy +async function playgroundProxy({url}) { + const targetUrl = url.searchParams.get('url'); + // eleventy only provides the URL + // approximate what the live playground does + const search = new URLSearchParams(); + search.set('url', targetUrl); + const proxyUrl = + new URL(`${PLAYGROUND_PROXY_HOST}/playground/proxy?${search}`); + const res = await fetch(proxyUrl, { + headers: { + 'Accept': 'application/ld+json, application/json' + } + }); + // create headers object and filter properties + // suffient for the site development purposes + const headers = Object.fromEntries( + Array.from(res.headers.entries()).filter( + v => !['content-length', 'content-encoding'].includes(v[0]))); + return { + status: res.status, + headers, + body: await res.text() + } +} diff --git a/.gitignore b/.gitignore index 7f0a39a1c..b64c927ed 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.backup *.sw[op] .DS_Store +.wrangler node_modules playground/jsonld.js _site diff --git a/README.md b/README.md index 110a20f37..34cd6856f 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,37 @@ A list of all previous specification drafts is also available. https://json-ld.org/spec/ -[list of users]: https://github.com/json-ld/json-ld.org/wiki/Users-of-JSON-LD +Website Development +------------------- + +- This site is published using [Eleventy][]. +- The site is deployed using [Cloudflare Pages][]. +- The [playground][] has a special proxy to handle `http:` URLs. + +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 +``` + +Additionally, if you want to use or test the playground `http:` proxy, also run +the [Wrangler][] server to emulate the [Cloudflare Pages Functions][] code: + +```sh +npm run dev +``` + +[Cloudflare Pages Functions]: https://developers.cloudflare.com/pages/functions/ +[Cloudflare Pages]: https://pages.cloudflare.com/ +[Eleventy]: https://www.11ty.dev/ [JSON-LD 1.1 - A JSON-based Serialization for Linked Data]: http://www.w3.org/TR/json-ld/ -[JSON-LD 1.1 Processing Algorithms and API]: https://www.w3.org/TR/json-ld-api/ [JSON-LD 1.1 Framing]: https://www.w3.org/TR/json-ld-framing/ +[JSON-LD 1.1 Processing Algorithms and API]: https://www.w3.org/TR/json-ld-api/ +[Wrangler]: https://developers.cloudflare.com/workers/wrangler/ +[list of users]: https://github.com/json-ld/json-ld.org/wiki/Users-of-JSON-LD +[playground]: https://json-ld.org/playground/ diff --git a/functions/playground/proxy.js b/functions/playground/proxy.js new file mode 100644 index 000000000..9fe3dc2af --- /dev/null +++ b/functions/playground/proxy.js @@ -0,0 +1,68 @@ +// json-ld.org playground proxy +// +// details: +// - Basic proxy for use with the json-ld.org playground. +// - Built for deployment using Cloudflare Pages Functions API +// - https://developers.cloudflare.com/pages/functions/ +// - Only handle GET requests. +// - Only designed to be used by the playground, no CORS support. +// - Only handle requests for 'http:' URLs. +// - Short timeout enough for expected development use cases. +// - Only support JSON-LD and JSON content types for target response. +// - Not intended to be very robust (but improvements welcome). +// +// usage: +// - GET /playground/proxy?url={encoded-url} +// - Proxy errors have JSON content and a +// 'X-JSON-LD-Playground-Proxy-Status' header. + +const RESPONSE_HEADER = 'X-JSON-LD-Playground-Proxy-Status'; + +function makeError({error}) { + return Response.json({error}, { + status: 400, + headers: { + [RESPONSE_HEADER]: '400' + } + }); +} + +export async function onRequestGet(context) { + const request = context.request; + try { + const requestUrl = new URL(request.url); + const targetUrl = new URL(requestUrl.searchParams.get('url')); + // check self request + if(targetUrl.host === requestUrl.host) { + return makeError({error: 'self request'}); + } + // check url protocol + if(targetUrl.protocol !== 'http:') { + return makeError({error: 'unsupported URL protocol'}); + } + // make similar request with new target url + const req = new Request(targetUrl, request); + const res = await fetch(req, { + redirect: 'follow', + // fail for long requests + signal: AbortSignal.timeout(3000) + }); + // check return type is JSON-LD or JSON + const ct = res.headers.get('content-type'); + if(!(ct === 'application/ld+json' || ct === 'application/json')) { + return makeError({error: 'unsupported response content type'}); + } + // check if remote seems to be the proxy itself + if(res.headers.has(RESPONSE_HEADER)) { + return makeError({error: 'playground proxy response found'}); + } + return res; + } catch(e) { + // special case timeout error + if(e.name === 'TimeoutError') { + return makeError({error: 'timeout'}); + } + // fallback error + return makeError({error: 'bad request'}); + } +} diff --git a/package.json b/package.json index 977106e8a..fc7e4bbd4 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,11 @@ "scripts": { "build": "eleventy", "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" }, "devDependencies": { - "@11ty/eleventy": "^2.0.1" + "@11ty/eleventy": "^3.0.0-alpha.9" } } diff --git a/playground/1.0/playground.js b/playground/1.0/playground.js index f78e031f5..988fef39d 100644 --- a/playground/1.0/playground.js +++ b/playground/1.0/playground.js @@ -1480,7 +1480,7 @@ // NOTE: using hard-coded path so file can be shared with dev page //location.pathname, '/playground/', - 'proxy.php?url=', + 'proxy?url=', url ].join(''); } diff --git a/playground/1.0/proxy.php b/playground/1.0/proxy.php deleted file mode 100644 index 683135e34..000000000 --- a/playground/1.0/proxy.php +++ /dev/null @@ -1,53 +0,0 @@ - $value){ - if($key == 'Host') - continue; - $headers_str[]=$key.': '.$value; - } - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers_str); - curl_setopt($ch, CURLOPT_ENCODING, ''); - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - $result = curl_exec($ch); - http_response_code(curl_getinfo($ch, CURLINFO_HTTP_CODE)); - header('Content-Type: '.curl_getinfo($ch, CURLINFO_CONTENT_TYPE)); - curl_close($ch); - echo $result; -} - -?> diff --git a/playground/playground.js b/playground/playground.js index bc880b688..b1a17dfaf 100644 --- a/playground/playground.js +++ b/playground/playground.js @@ -1638,7 +1638,7 @@ // NOTE: using hard-coded path so file can be shared with dev page //location.pathname, '/playground/', - 'proxy.php?url=', + 'proxy?url=', url ].join(''); } diff --git a/playground/proxy.php b/playground/proxy.php deleted file mode 100644 index 683135e34..000000000 --- a/playground/proxy.php +++ /dev/null @@ -1,53 +0,0 @@ - $value){ - if($key == 'Host') - continue; - $headers_str[]=$key.': '.$value; - } - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers_str); - curl_setopt($ch, CURLOPT_ENCODING, ''); - curl_setopt($ch, CURLOPT_TIMEOUT, 10); - $result = curl_exec($ch); - http_response_code(curl_getinfo($ch, CURLINFO_HTTP_CODE)); - header('Content-Type: '.curl_getinfo($ch, CURLINFO_CONTENT_TYPE)); - curl_close($ch); - echo $result; -} - -?> From b3aa460679cb445478b7a36c2f1193f05601d0eb Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 12:00:35 -0400 Subject: [PATCH 09/33] 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 fc7e4bbd4..aea57bc57 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 0dfc72bfd3c91a2e157fccfd7e44537811fda28c Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 12:01:31 -0400 Subject: [PATCH 10/33] Ignore package-lock.json. --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b64c927ed..0d5760310 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 255762529459604b25a7c55d58c41c678fb05d10 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:46:57 -0400 Subject: [PATCH 11/33] Add .editorconfig. --- .editorconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..5d47c21c4 --- /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 0f90edc228da20518e4d180b88581540a9877ff8 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 09:45:52 -0400 Subject: [PATCH 12/33] 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 aea57bc57..e3797eb51 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 0504c10a2e47ba91ecd2b8e096f5f3aaf2e88e57 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 09:48:51 -0400 Subject: [PATCH 13/33] Add info about npm run build & pages. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 34cd6856f..1b7e0d93f 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 4162056ce387045fdb8c4cddee513b62f4b28377 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 09:44:37 -0400 Subject: [PATCH 14/33] Copy over _headers and _redirects. --- .eleventy.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.eleventy.js b/.eleventy.js index 096e6fb9a..d199c37d2 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 7fd7d12644d505e94d78bebf1391f561486cf441 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:39:03 -0400 Subject: [PATCH 15/33] 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 84c18f9ff..000000000 --- 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 000000000..13fdff49c --- /dev/null +++ b/_redirects @@ -0,0 +1 @@ +/playground-dev /playground 302 From ae855ead763f79ef6ef526148ac7aca968a046ae Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:40:09 -0400 Subject: [PATCH 16/33] 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 d199c37d2..7a7dcf348 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 ee8e4d25e..000000000 --- a/images/.htaccess +++ /dev/null @@ -1,10 +0,0 @@ - - order allow,deny - deny from all - - - - order allow,deny - deny from all - - From 55bea6fa240bcc93a17fc67a7bb019bf5f4c7479 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:42:48 -0400 Subject: [PATCH 17/33] 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 000000000..418281ada --- /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 13fdff49c..dde88850d 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 a8f948ec7..000000000 --- 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 612b36da43190c234e482d8dfb052eeabf79a042 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:44:26 -0400 Subject: [PATCH 18/33] 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 3b8be4f70..000000000 --- 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 39d6139a87641dddc67ad3fbfd8d2e393e0aeedf Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Thu, 27 Mar 2025 16:45:06 -0400 Subject: [PATCH 19/33] 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 dde88850d..f4592c243 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 af6788fc5..000000000 --- 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 f40f13722edc2c80f0a39bbb25f751b28f833e66 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 09:51:04 -0400 Subject: [PATCH 20/33] 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 b9ba71943..49526412b 100644 --- a/404.html +++ b/404.html @@ -16,15 +16,15 @@ - - - + + + - + @@ -53,10 +53,10 @@
  • -
  • Branding
  • +
  • Branding
  • From ffeb8445503f524830fcd29d7c2bceebc06de05e Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 11:52:16 -0400 Subject: [PATCH 21/33] 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 000000000..9a6a7c3d4 --- /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 9ca4fb57e..000000000 --- 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 df0ce8eeb726bf2f591dba103d92211e28e038fc Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 13:59:38 -0400 Subject: [PATCH 22/33] 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 9a6a7c3d4..bc2db3b83 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 731c01f3985ce91748d20e45560b2af23f2d948f Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 14:26:30 -0400 Subject: [PATCH 23/33] 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 418281ada..5764fc514 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 f4592c243..41d47b027 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 45a04ae85..000000000 --- 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 b91a537aa8988a332ec3ffef0c81632887a0c022 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Mon, 31 Mar 2025 14:29:39 -0400 Subject: [PATCH 24/33] 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 7a7dcf348..56950b549 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 d5d0d53bd..000000000 --- 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 8bb70691c..000000000 --- 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 97296748b..000000000 --- a/utils/git.php +++ /dev/null @@ -1,74 +0,0 @@ - From 3e7ac45dfcc3d08e86a47e1277231f0f4387ee3c Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Tue, 1 Apr 2025 16:18:43 -0400 Subject: [PATCH 25/33] 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 56950b549..2ce0822f7 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 e3797eb51..77bbf783b 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 5d9597f64..a3650db65 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 83967fda0..a54ae4710 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 515c98a50c680d53ce9565871298b333f954c6d1 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Tue, 1 Apr 2025 16:58:58 -0400 Subject: [PATCH 26/33] 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 000000000..bbd92ea85 --- /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 717bd90feebe05aef5ac53c30ef0dfcd22fcf9ea Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 10:27:05 -0400 Subject: [PATCH 27/33] 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 bbd92ea85..e3171f4f7 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 545d6dc4cc18f06edbe87677344882589cf2810c Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 10:27:43 -0400 Subject: [PATCH 28/33] Optimize _headers order and format. --- _headers | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/_headers b/_headers index 5764fc514..8cede675b 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 1297213fc37fa5274d2bbdcf9be3c279a946ed9c Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 10:29:13 -0400 Subject: [PATCH 29/33] 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 e3171f4f7..686d3250a 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 b4ebf2767a157cb55751934249400d5a6a5c187b Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 11:00:14 -0400 Subject: [PATCH 30/33] 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 686d3250a..f0775ed05 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 4fedf473f84d1a64adb9f111827f916b6dd43cca Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 11:07:16 -0400 Subject: [PATCH 31/33] Optimize redirect order; https for schema.org. --- _redirects | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_redirects b/_redirects index 41d47b027..719487ebe 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 69343409331b990d0a83ce79cef79cf4b33ac837 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 11:07:33 -0400 Subject: [PATCH 32/33] Set wrangler compatibility date. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 77bbf783b..f013ec84d 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 a66b568f0a02f8703120adbd9f08f82df075ae53 Mon Sep 17 00:00:00 2001 From: Benjamin Young Date: Wed, 2 Apr 2025 11:19:52 -0400 Subject: [PATCH 33/33] 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 1b7e0d93f..cd9a3bcc7 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 f013ec84d..a1e31927a 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"