From 43bbaae2585cc63f16591580dd75baf30106b066 Mon Sep 17 00:00:00 2001 From: Lars Trieloff Date: Fri, 26 Nov 2021 18:37:17 +0100 Subject: [PATCH 1/2] test(pipeline): add a test that demonstrates how to use a custom react component as the main function of a custom pipeline uses `React.createElement`, so I don't have to worry about JSX and bundlers. Uses `getServerSideProps` like next.js, this could be used to fetch additional data from a GraphQL endpoint --- package-lock.json | 288 +++++++++++++++++++++++++-- package.json | 2 + src/schemas/context.schema.json | 3 + test/fixtures/react-app/.eslintrc.js | 16 ++ test/fixtures/react-app/index.mjs | 32 +++ test/testReactInPipeline.js | 121 +++++++++++ 6 files changed, 446 insertions(+), 16 deletions(-) create mode 100644 test/fixtures/react-app/.eslintrc.js create mode 100644 test/fixtures/react-app/index.mjs create mode 100644 test/testReactInPipeline.js diff --git a/package-lock.json b/package-lock.json index bbfc38f35..1aa185148 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@adobe/helix-pipeline", - "version": "15.0.8", + "version": "15.0.9", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@adobe/helix-pipeline", - "version": "15.0.8", + "version": "15.0.9", "license": "Apache-2.0", "dependencies": { "@adobe/helix-fetch": "3.0.0", @@ -84,6 +84,8 @@ "nock": "13.2.1", "nyc": "15.1.0", "proxyquire": "2.1.3", + "react": "17.0.2", + "react-dom": "17.0.2", "semantic-release": "18.0.0", "sinon": "12.0.1", "unist-builder": "2.0.3", @@ -9966,6 +9968,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -11649,7 +11663,184 @@ "treeverse", "validate-npm-package-name", "which", - "write-file-atomic" + "write-file-atomic", + "@gar/promisify", + "@npmcli/disparity-colors", + "@npmcli/fs", + "@npmcli/git", + "@npmcli/installed-package-contents", + "@npmcli/metavuln-calculator", + "@npmcli/move-file", + "@npmcli/name-from-folder", + "@npmcli/node-gyp", + "@npmcli/promise-spawn", + "@tootallnate/once", + "agent-base", + "agentkeepalive", + "aggregate-error", + "ajv", + "ansi-regex", + "ansi-styles", + "aproba", + "are-we-there-yet", + "asap", + "asn1", + "assert-plus", + "asynckit", + "aws-sign2", + "aws4", + "balanced-match", + "bcrypt-pbkdf", + "bin-links", + "binary-extensions", + "brace-expansion", + "builtins", + "caseless", + "cidr-regex", + "clean-stack", + "clone", + "cmd-shim", + "code-point-at", + "color-convert", + "color-name", + "color-support", + "colors", + "combined-stream", + "common-ancestor-path", + "concat-map", + "console-control-strings", + "core-util-is", + "dashdash", + "debug", + "debuglog", + "defaults", + "delayed-stream", + "delegates", + "depd", + "dezalgo", + "diff", + "ecc-jsbn", + "emoji-regex", + "encoding", + "env-paths", + "err-code", + "extend", + "extsprintf", + "fast-deep-equal", + "fast-json-stable-stringify", + "forever-agent", + "fs-minipass", + "fs.realpath", + "function-bind", + "gauge", + "getpass", + "har-schema", + "har-validator", + "has", + "has-flag", + "has-unicode", + "http-cache-semantics", + "http-proxy-agent", + "http-signature", + "https-proxy-agent", + "humanize-ms", + "iconv-lite", + "ignore-walk", + "imurmurhash", + "indent-string", + "infer-owner", + "inflight", + "inherits", + "ip", + "ip-regex", + "is-core-module", + "is-fullwidth-code-point", + "is-lambda", + "is-typedarray", + "isexe", + "isstream", + "jsbn", + "json-schema", + "json-schema-traverse", + "json-stringify-nice", + "json-stringify-safe", + "jsonparse", + "jsprim", + "just-diff", + "just-diff-apply", + "lru-cache", + "mime-db", + "mime-types", + "minimatch", + "minipass-collect", + "minipass-fetch", + "minipass-flush", + "minipass-json-stream", + "minipass-sized", + "minizlib", + "mute-stream", + "negotiator", + "normalize-package-data", + "npm-bundled", + "npm-normalize-package-bin", + "npm-packlist", + "number-is-nan", + "oauth-sign", + "object-assign", + "once", + "p-map", + "path-is-absolute", + "performance-now", + "proc-log", + "promise-all-reject-late", + "promise-call-limit", + "promise-inflight", + "promise-retry", + "promzard", + "psl", + "punycode", + "qs", + "read-cmd-shim", + "readable-stream", + "request", + "retry", + "safe-buffer", + "safer-buffer", + "set-blocking", + "signal-exit", + "smart-buffer", + "socks", + "socks-proxy-agent", + "spdx-correct", + "spdx-exceptions", + "spdx-expression-parse", + "spdx-license-ids", + "sshpk", + "string_decoder", + "string-width", + "stringify-package", + "strip-ansi", + "supports-color", + "tunnel-agent", + "tweetnacl", + "typedarray-to-buffer", + "unique-filename", + "unique-slug", + "uri-js", + "util-deprecate", + "uuid", + "validate-npm-package-license", + "verror", + "walk-up-path", + "wcwidth", + "wide-align", + "wrappy", + "yallist", + "form-data", + "isarray", + "path-parse", + "process-nextick-args", + "resolve" ], "dev": true, "dependencies": { @@ -14193,11 +14384,6 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, "engines": { "node": ">=0.10.0" } @@ -15797,6 +15983,33 @@ "node": ">=0.10.0" } }, + "node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" + } + }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -16501,6 +16714,16 @@ "node": ">=10" } }, + "node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "node_modules/semantic-release": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-18.0.0.tgz", @@ -17530,11 +17753,6 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, "engines": { "node": ">=0.10.0" } @@ -21801,9 +22019,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "requires": { - "ajv": "^8.0.0" - } + "requires": {} }, "ansi-colors": { "version": "4.1.1", @@ -27699,6 +27915,15 @@ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==" }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -32002,6 +32227,27 @@ } } }, + "react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + } + }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -32532,6 +32778,16 @@ "xmlchars": "^2.2.0" } }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "semantic-release": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-18.0.0.tgz", diff --git a/package.json b/package.json index 37553ac9a..1bf31919b 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,8 @@ "nock": "13.2.1", "nyc": "15.1.0", "proxyquire": "2.1.3", + "react": "17.0.2", + "react-dom": "17.0.2", "semantic-release": "18.0.0", "sinon": "12.0.1", "unist-builder": "2.0.3", diff --git a/src/schemas/context.schema.json b/src/schemas/context.schema.json index 49c8a86e0..9b8194e17 100644 --- a/src/schemas/context.schema.json +++ b/src/schemas/context.schema.json @@ -30,6 +30,9 @@ }, "response": { "$ref": "https://ns.adobe.com/helix/pipeline/response" + }, + "props": { + "type": "object" } } } diff --git a/test/fixtures/react-app/.eslintrc.js b/test/fixtures/react-app/.eslintrc.js new file mode 100644 index 000000000..c50651044 --- /dev/null +++ b/test/fixtures/react-app/.eslintrc.js @@ -0,0 +1,16 @@ +/* + * Copyright 2021 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +module.exports = { + parserOptions: { + sourceType: 'module', + }, +}; diff --git a/test/fixtures/react-app/index.mjs b/test/fixtures/react-app/index.mjs new file mode 100644 index 000000000..34ac7f25c --- /dev/null +++ b/test/fixtures/react-app/index.mjs @@ -0,0 +1,32 @@ +/* + * Copyright 2021 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import React from 'react'; + +const e = React.createElement; + +export async function getServerSideProps() { + console.log('fetching additional stuff'); + return { additional: 'stuff' }; +} + +export default class App extends React.Component { + // eslint-disable-next-line class-methods-use-this + render() { + return e( + 'div', + { }, + this.props.additional, + ' ', + e('i', { className: 'its-not-semantic-html-but-i-like-it' }, 'World'), + ); + } +} diff --git a/test/testReactInPipeline.js b/test/testReactInPipeline.js new file mode 100644 index 000000000..b7836f144 --- /dev/null +++ b/test/testReactInPipeline.js @@ -0,0 +1,121 @@ +/* + * Copyright 2018 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +/* eslint-env mocha */ +const assert = require('assert'); +const { logging } = require('@adobe/helix-testutils'); +const ReactDOMServer = require('react-dom/server'); +const { setupPolly, pipe } = require('./utils.js'); + +const logger = logging.createTestLogger({ + // tune this for debugging + level: 'info', +}); + +const params = { + path: '/hello.md', + __ow_method: 'get', + owner: 'trieloff', + __ow_headers: { + 'X-Forwarded-Port': '443', + 'X-CDN-Request-Id': '2a208a89-e071-44cf-aee9-220880da4c1e', + 'Fastly-Client': '1', + 'X-Forwarded-Host': 'runtime.adobe.io', + 'Upgrade-Insecure-Requests': '1', + Host: 'controller-a', + Connection: 'close', + 'Fastly-SSL': '1', + 'X-Request-Id': 'RUss5tPdgOfw74a68aNc24FeTipGpVfW', + 'X-Branch': 'master', + 'Accept-Language': 'en-US, en;q=0.9, de;q=0.8', + 'X-Forwarded-Proto': 'https', + 'Fastly-Orig-Accept-Encoding': 'gzip', + 'X-Varnish': '267021320', + DNT: '1', + 'X-Forwarded-For': + '192.147.117.11, 157.52.92.27, 23.235.46.33, 10.64.221.107', + 'X-Host': 'www.primordialsoup.life', + Accept: + 'text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, image/apng, */*;q=0.8', + 'X-Real-IP': '10.64.221.107', + 'X-Forwarded-Server': 'cache-lcy19249-LCY, cache-iad2127-IAD', + 'Fastly-Client-IP': '192.147.117.11', + 'Perf-Br-Req-In': '1529585370.116', + 'X-Timer': 'S1529585370.068237,VS0,VS0', + 'Fastly-FF': + 'dc/x3e9z8KMmlHLQr8BEvVMmTcpl3y2YY5y6gjSJa3g=!LCY!cache-lcy19249-LCY, dc/x3e9z8KMmlHLQr8BEvVMmTcpl3y2YY5y6gjSJa3g=!LCY!cache-lcy19227-LCY, dc/x3e9z8KMmlHLQr8BEvVMmTcpl3y2YY5y6gjSJa3g=!IAD!cache-iad2127-IAD, dc/x3e9z8KMmlHLQr8BEvVMmTcpl3y2YY5y6gjSJa3g=!IAD!cache-iad2133-IAD', + 'Accept-Encoding': 'gzip', + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36', + }, + repo: 'soupdemo', + ref: 'master', + selector: 'md', +}; + +const secrets = { + REPO_RAW_ROOT: 'https://raw.githubusercontent.com/', +}; + +const crequest = { + extension: 'html', + url: '/test/test.html', +}; + +describe('Testing HTML Pipeline Overrides', () => { + setupPolly({ + recordIfMissing: false, + }); + + it('html.pipe adds headers from meta and link tags', async () => { + const mycomponent = await import('./fixtures/react-app/index.mjs'); + const Mycomponent = mycomponent.default; + + const myfunc = (context) => { + let body = ''; + try { + body = ReactDOMServer.renderToString(new Mycomponent(context.props).render()); + } catch (e) { + body = e.message; + } + + context.response = { + body: `${body}`, + }; + }; + + myfunc.after = { + fetch: async (context) => { + if (typeof mycomponent.getServerSideProps === 'function') { + context.props = mycomponent.getServerSideProps(context); + } + }, + }; + + const result = await pipe( + myfunc, + { + request: crequest, + content: { + body: 'Hello _World_', + }, + }, + { + request: { params }, + secrets, + logger, + }, + ); + + console.log(result.response.body); + assert.ok(result.response.body.match(/World<\/i>/)); + }); +}); From a4413736f69d0640eb6dd3674337a225ef964881 Mon Sep 17 00:00:00 2001 From: CircleCi Build Date: Fri, 26 Nov 2021 17:40:06 +0000 Subject: [PATCH 2/2] chore(docs): updating documentation --- docs/README.md | 2 ++ docs/context-properties-props.md | 15 +++++++++++++++ docs/context.md | 19 +++++++++++++++++++ docs/context.schema.json | 2 +- 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 docs/context-properties-props.md diff --git a/docs/README.md b/docs/README.md index 8e9642188..b398037ea 100644 --- a/docs/README.md +++ b/docs/README.md @@ -52,6 +52,8 @@ * [Untitled object in Content](./content-properties-data.md "Custom object that can hold any user defined data") – `https://ns.adobe.com/helix/pipeline/content#/properties/data` +* [Untitled object in Context](./context-properties-props.md) – `https://ns.adobe.com/helix/pipeline/context#/properties/props` + * [Untitled object in MDAST](./mdast-properties-payload.md "The payload of a frontmatter/yaml block") – `https://ns.adobe.com/helix/pipeline/mdast#/properties/payload` * [Untitled object in MDAST](./mdast-properties-data.md "data is guaranteed to never be specified by unist or specifications implementing unist") – `https://ns.adobe.com/helix/pipeline/mdast#/properties/data` diff --git a/docs/context-properties-props.md b/docs/context-properties-props.md new file mode 100644 index 000000000..7c9067830 --- /dev/null +++ b/docs/context-properties-props.md @@ -0,0 +1,15 @@ +# Untitled object in Context Schema + +```txt +https://ns.adobe.com/helix/pipeline/context#/properties/props +``` + + + +| Abstract | Extensible | Status | Identifiable | Custom Properties | Additional Properties | Access Restrictions | Defined In | +| :------------------ | :--------- | :------------- | :---------------------- | :---------------- | :-------------------- | :------------------ | :----------------------------------------------------------------- | +| Can be instantiated | No | Unknown status | Unknown identifiability | Forbidden | Allowed | none | [context.schema.json*](context.schema.json "open original schema") | + +## props Type + +`object` ([Details](context-properties-props.md)) diff --git a/docs/context.md b/docs/context.md index 2c1ce1c21..57c1d7d0f 100644 --- a/docs/context.md +++ b/docs/context.md @@ -22,6 +22,7 @@ The context thingie. | [request](#request) | `object` | Optional | cannot be null | [Context](context-properties-request.md "https://ns.adobe.com/helix/pipeline/request#/properties/request") | | [content](#content) | `object` | Optional | cannot be null | [Context](context-properties-content.md "https://ns.adobe.com/helix/pipeline/content#/properties/content") | | [response](#response) | `object` | Optional | cannot be null | [Context](context-properties-response.md "https://ns.adobe.com/helix/pipeline/response#/properties/response") | +| [props](#props) | `object` | Optional | cannot be null | [Context](context-properties-props.md "https://ns.adobe.com/helix/pipeline/context#/properties/props") | ## error @@ -95,3 +96,21 @@ The HTTP response object ### response Type `object` ([Response](context-properties-response.md)) + +## props + + + +`props` + +* is optional + +* Type: `object` ([Details](context-properties-props.md)) + +* cannot be null + +* defined in: [Context](context-properties-props.md "https://ns.adobe.com/helix/pipeline/context#/properties/props") + +### props Type + +`object` ([Details](context-properties-props.md)) diff --git a/docs/context.schema.json b/docs/context.schema.json index fa0b8bc84..d172dedfb 100644 --- a/docs/context.schema.json +++ b/docs/context.schema.json @@ -1 +1 @@ -{"meta:license":["Copyright 2018 Adobe. All rights reserved.","This file is licensed to you under the Apache License, Version 2.0 (the \"License\");","you may not use this file except in compliance with the License. You may obtain a copy","of the License at http://www.apache.org/licenses/LICENSE-2.0","","Unless required by applicable law or agreed to in writing, software distributed under","the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS","OF ANY KIND, either express or implied. See the License for the specific language","governing permissions and limitations under the License."],"$id":"https://ns.adobe.com/helix/pipeline/context","$schema":"http://json-schema.org/draft-07/schema#","title":"Context","type":"object","meta:status":"stabilizing","description":"The context thingie.","additionalProperties":false,"properties":{"error":{"type":["string","object"],"description":"An error message that has been generated during pipeline processing.\nWhen this property is present, all other values can be ignored."},"request":{"$ref":"https://ns.adobe.com/helix/pipeline/request"},"content":{"$ref":"https://ns.adobe.com/helix/pipeline/content"},"response":{"$ref":"https://ns.adobe.com/helix/pipeline/response"}}} +{"meta:license":["Copyright 2018 Adobe. All rights reserved.","This file is licensed to you under the Apache License, Version 2.0 (the \"License\");","you may not use this file except in compliance with the License. You may obtain a copy","of the License at http://www.apache.org/licenses/LICENSE-2.0","","Unless required by applicable law or agreed to in writing, software distributed under","the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS","OF ANY KIND, either express or implied. See the License for the specific language","governing permissions and limitations under the License."],"$id":"https://ns.adobe.com/helix/pipeline/context","$schema":"http://json-schema.org/draft-07/schema#","title":"Context","type":"object","meta:status":"stabilizing","description":"The context thingie.","additionalProperties":false,"properties":{"error":{"type":["string","object"],"description":"An error message that has been generated during pipeline processing.\nWhen this property is present, all other values can be ignored."},"request":{"$ref":"https://ns.adobe.com/helix/pipeline/request"},"content":{"$ref":"https://ns.adobe.com/helix/pipeline/content"},"response":{"$ref":"https://ns.adobe.com/helix/pipeline/response"},"props":{"type":"object"}}}