parent
78cadc3eb8
commit
9055384033
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,3 @@ |
|||||||
|
{ |
||||||
|
"extends": ["../../.eslintrc"] |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. |
||||||
|
|
||||||
|
# dependencies |
||||||
|
/node_modules |
||||||
|
/.pnp |
||||||
|
.pnp.js |
||||||
|
|
||||||
|
# testing |
||||||
|
/coverage |
||||||
|
|
||||||
|
# production |
||||||
|
/build |
||||||
|
|
||||||
|
# misc |
||||||
|
.DS_Store |
||||||
|
.env.local |
||||||
|
.env.development.local |
||||||
|
.env.test.local |
||||||
|
.env.production.local |
||||||
|
|
||||||
|
npm-debug.log* |
||||||
|
yarn-debug.log* |
||||||
|
yarn-error.log* |
@ -0,0 +1,21 @@ |
|||||||
|
MIT License |
||||||
|
|
||||||
|
Copyright (c) 2023 Jackson Morgan |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
SOFTWARE. |
@ -0,0 +1,12 @@ |
|||||||
|
# LDO Demo-React |
||||||
|
|
||||||
|
A demo app to show off the use of LDO. |
||||||
|
|
||||||
|
## Sponsorship |
||||||
|
This project was made possible by a grant from NGI Zero Entrust via nlnet. Learn more on the [NLnet project page](https://nlnet.nl/project/SolidUsableApps/). |
||||||
|
|
||||||
|
[<img src="https://nlnet.nl/logo/banner.png" alt="nlnet foundation logo" width="300" />](https://nlnet.nl/) |
||||||
|
[<img src="https://nlnet.nl/image/logos/NGI0Entrust_tag.svg" alt="NGI Zero Entrust Logo" width="300" />](https://nlnet.nl/) |
||||||
|
|
||||||
|
## Liscense |
||||||
|
MIT |
@ -0,0 +1,28 @@ |
|||||||
|
// this file overrides the default CRA configurations (webpack, eslint, babel, etc)
|
||||||
|
// Ingnore because config scripts can't use the import variable
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin"); |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
webpack: { |
||||||
|
configure: (config) => { |
||||||
|
// Remove ModuleScopePlugin which throws when we try to import something
|
||||||
|
// outside of src/.
|
||||||
|
config.resolve.plugins.pop(); |
||||||
|
|
||||||
|
// Resolve the path aliases.
|
||||||
|
config.resolve.plugins.push(new TsconfigPathsPlugin()); |
||||||
|
|
||||||
|
// Let Babel compile outside of src/.
|
||||||
|
const oneOfRule = config.module.rules.find((rule) => rule.oneOf); |
||||||
|
const tsRule = oneOfRule.oneOf.find((rule) => |
||||||
|
rule.test.toString().includes("ts|tsx"), |
||||||
|
); |
||||||
|
|
||||||
|
tsRule.include = undefined; |
||||||
|
tsRule.exclude = /node_modules/; |
||||||
|
|
||||||
|
return config; |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
@ -0,0 +1,50 @@ |
|||||||
|
{ |
||||||
|
"name": "@ldo/demo-react", |
||||||
|
"version": "0.0.1-alpha.19", |
||||||
|
"dependencies": { |
||||||
|
"@inrupt/solid-client-authn-browser": "^2.0.0", |
||||||
|
"@ldo/solid-react": "^0.0.1-alpha.19", |
||||||
|
"react": "^18.2.0", |
||||||
|
"react-dom": "^18.2.0", |
||||||
|
"react-router-dom": "^6.15.0", |
||||||
|
"react-scripts": "5.0.1", |
||||||
|
"uuid": "^9.0.1" |
||||||
|
}, |
||||||
|
"scripts": { |
||||||
|
"start": "craco start", |
||||||
|
"build": "craco build", |
||||||
|
"eject": "react-scripts eject", |
||||||
|
"lint": "eslint src/** --fix --no-error-on-unmatched-pattern", |
||||||
|
"build:ldo": "ldo build --input src/.shapes --output src/.ldo" |
||||||
|
}, |
||||||
|
"eslintConfig": { |
||||||
|
"extends": [ |
||||||
|
"react-app", |
||||||
|
"react-app/jest" |
||||||
|
] |
||||||
|
}, |
||||||
|
"browserslist": { |
||||||
|
"production": [ |
||||||
|
">0.2%", |
||||||
|
"not dead", |
||||||
|
"not op_mini all" |
||||||
|
], |
||||||
|
"development": [ |
||||||
|
"last 1 firefox version", |
||||||
|
"last 1 chrome version", |
||||||
|
"last 1 safari version" |
||||||
|
] |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@craco/craco": "^7.1.0", |
||||||
|
"@ldo/cli": "^0.0.1-alpha.19", |
||||||
|
"@types/jsonld": "^1.5.9", |
||||||
|
"@types/react": "^18.2.21", |
||||||
|
"@types/shexj": "^2.1.4", |
||||||
|
"tsconfig-paths-webpack-plugin": "^4.1.0" |
||||||
|
}, |
||||||
|
"gitHead": "4548985c0de9b0ec83cf5ee93f2d7c1ca2c1b8d8", |
||||||
|
"publishConfig": { |
||||||
|
"access": "public" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8" /> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
||||||
|
<meta name="theme-color" content="#000000" /> |
||||||
|
<meta |
||||||
|
name="description" |
||||||
|
content="Web site created using create-react-app" |
||||||
|
/> |
||||||
|
<!-- |
||||||
|
manifest.json provides metadata used when your web app is installed on a |
||||||
|
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ |
||||||
|
--> |
||||||
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> |
||||||
|
<!-- |
||||||
|
Notice the use of %PUBLIC_URL% in the tags above. |
||||||
|
It will be replaced with the URL of the `public` folder during the build. |
||||||
|
Only files inside the `public` folder can be referenced from the HTML. |
||||||
|
|
||||||
|
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will |
||||||
|
work correctly both with client-side routing and a non-root public URL. |
||||||
|
Learn how to configure a non-root public URL by running `npm run build`. |
||||||
|
--> |
||||||
|
<title>React App</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript> |
||||||
|
<div id="root"></div> |
||||||
|
<!-- |
||||||
|
This HTML file is a template. |
||||||
|
If you open it directly in the browser, you will see an empty page. |
||||||
|
|
||||||
|
You can add webfonts, meta tags, or analytics to this file. |
||||||
|
The build step will place the bundled scripts into the <body> tag. |
||||||
|
|
||||||
|
To begin the development, run `npm start` or `yarn start`. |
||||||
|
To create a production bundle, use `npm run build` or `yarn build`. |
||||||
|
--> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,25 @@ |
|||||||
|
{ |
||||||
|
"short_name": "React App", |
||||||
|
"name": "Create React App Sample", |
||||||
|
"icons": [ |
||||||
|
{ |
||||||
|
"src": "favicon.ico", |
||||||
|
"sizes": "64x64 32x32 24x24 16x16", |
||||||
|
"type": "image/x-icon" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"src": "logo192.png", |
||||||
|
"type": "image/png", |
||||||
|
"sizes": "192x192" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"src": "logo512.png", |
||||||
|
"type": "image/png", |
||||||
|
"sizes": "512x512" |
||||||
|
} |
||||||
|
], |
||||||
|
"start_url": ".", |
||||||
|
"display": "standalone", |
||||||
|
"theme_color": "#000000", |
||||||
|
"background_color": "#ffffff" |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
# https://www.robotstxt.org/robotstxt.html |
||||||
|
User-agent: * |
||||||
|
Disallow: |
@ -0,0 +1,31 @@ |
|||||||
|
import { ContextDefinition } from "jsonld"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* postContext: JSONLD Context for post |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
export const postContext: ContextDefinition = { |
||||||
|
type: { |
||||||
|
"@id": "@type", |
||||||
|
}, |
||||||
|
SocialMediaPosting: "http://schema.org/SocialMediaPosting", |
||||||
|
CreativeWork: "http://schema.org/CreativeWork", |
||||||
|
Thing: "http://schema.org/Thing", |
||||||
|
articleBody: { |
||||||
|
"@id": "http://schema.org/articleBody", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
uploadDate: { |
||||||
|
"@id": "http://schema.org/uploadDate", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#date", |
||||||
|
}, |
||||||
|
image: { |
||||||
|
"@id": "http://schema.org/image", |
||||||
|
"@type": "@id", |
||||||
|
}, |
||||||
|
publisher: { |
||||||
|
"@id": "http://schema.org/publisher", |
||||||
|
"@type": "@id", |
||||||
|
}, |
||||||
|
}; |
@ -0,0 +1,155 @@ |
|||||||
|
import { Schema } from "shexj"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* postSchema: ShexJ Schema for post |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
export const postSchema: Schema = { |
||||||
|
type: "Schema", |
||||||
|
shapes: [ |
||||||
|
{ |
||||||
|
id: "https://example.com/PostSh", |
||||||
|
type: "ShapeDecl", |
||||||
|
shapeExpr: { |
||||||
|
type: "Shape", |
||||||
|
expression: { |
||||||
|
type: "EachOf", |
||||||
|
expressions: [ |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
values: [ |
||||||
|
"http://schema.org/SocialMediaPosting", |
||||||
|
"http://schema.org/CreativeWork", |
||||||
|
"http://schema.org/Thing", |
||||||
|
], |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://schema.org/articleBody", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#label", |
||||||
|
object: { |
||||||
|
value: "articleBody", |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The actual body of the article. ", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://schema.org/uploadDate", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#date", |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#label", |
||||||
|
object: { |
||||||
|
value: "uploadDate", |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"Date when this media object was uploaded to this site.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://schema.org/image", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#label", |
||||||
|
object: { |
||||||
|
value: "image", |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"A media object that encodes this CreativeWork. This property is a synonym for encoding.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://schema.org/publisher", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#label", |
||||||
|
object: { |
||||||
|
value: "publisher", |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The publisher of the creative work.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#label", |
||||||
|
object: { |
||||||
|
value: "SocialMediaPost", |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"A post to a social media platform, including blog posts, tweets, Facebook posts, etc.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}; |
@ -0,0 +1,19 @@ |
|||||||
|
import { ShapeType } from "@ldo/ldo"; |
||||||
|
import { postSchema } from "./post.schema"; |
||||||
|
import { postContext } from "./post.context"; |
||||||
|
import { PostSh } from "./post.typings"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* LDO ShapeTypes post |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* PostSh ShapeType |
||||||
|
*/ |
||||||
|
export const PostShShapeType: ShapeType<PostSh> = { |
||||||
|
schema: postSchema, |
||||||
|
shape: "https://example.com/PostSh", |
||||||
|
context: postContext, |
||||||
|
}; |
@ -0,0 +1,45 @@ |
|||||||
|
import { ContextDefinition } from "jsonld"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* Typescript Typings for post |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* PostSh Type |
||||||
|
*/ |
||||||
|
export interface PostSh { |
||||||
|
"@id"?: string; |
||||||
|
"@context"?: ContextDefinition; |
||||||
|
type: |
||||||
|
| { |
||||||
|
"@id": "SocialMediaPosting"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "CreativeWork"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Thing"; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* The actual body of the article. |
||||||
|
*/ |
||||||
|
articleBody?: string; |
||||||
|
/** |
||||||
|
* Date when this media object was uploaded to this site. |
||||||
|
*/ |
||||||
|
uploadDate: string; |
||||||
|
/** |
||||||
|
* A media object that encodes this CreativeWork. This property is a synonym for encoding. |
||||||
|
*/ |
||||||
|
image?: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* The publisher of the creative work. |
||||||
|
*/ |
||||||
|
publisher: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,154 @@ |
|||||||
|
import { ContextDefinition } from "jsonld"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* solidProfileContext: JSONLD Context for solidProfile |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
export const solidProfileContext: ContextDefinition = { |
||||||
|
type: { |
||||||
|
"@id": "@type", |
||||||
|
}, |
||||||
|
Person: "http://schema.org/Person", |
||||||
|
Person2: "http://xmlns.com/foaf/0.1/Person", |
||||||
|
fn: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#fn", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
name: { |
||||||
|
"@id": "http://xmlns.com/foaf/0.1/name", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
hasAddress: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#hasAddress", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
countryName: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#country-name", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
locality: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#locality", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
postalCode: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#postal-code", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
region: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#region", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
streetAddress: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#street-address", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
hasEmail: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#hasEmail", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
Dom: "http://www.w3.org/2006/vcard/ns#Dom", |
||||||
|
Home: "http://www.w3.org/2006/vcard/ns#Home", |
||||||
|
ISDN: "http://www.w3.org/2006/vcard/ns#ISDN", |
||||||
|
Internet: "http://www.w3.org/2006/vcard/ns#Internet", |
||||||
|
Intl: "http://www.w3.org/2006/vcard/ns#Intl", |
||||||
|
Label: "http://www.w3.org/2006/vcard/ns#Label", |
||||||
|
Parcel: "http://www.w3.org/2006/vcard/ns#Parcel", |
||||||
|
Postal: "http://www.w3.org/2006/vcard/ns#Postal", |
||||||
|
Pref: "http://www.w3.org/2006/vcard/ns#Pref", |
||||||
|
Work: "http://www.w3.org/2006/vcard/ns#Work", |
||||||
|
X400: "http://www.w3.org/2006/vcard/ns#X400", |
||||||
|
value: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#value", |
||||||
|
"@type": "@id", |
||||||
|
}, |
||||||
|
hasPhoto: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#hasPhoto", |
||||||
|
"@type": "@id", |
||||||
|
}, |
||||||
|
img: { |
||||||
|
"@id": "http://xmlns.com/foaf/0.1/img", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
hasTelephone: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#hasTelephone", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
phone: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#phone", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
organizationName: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#organization-name", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
role: { |
||||||
|
"@id": "http://www.w3.org/2006/vcard/ns#role", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
trustedApp: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/acl#trustedApp", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
mode: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/acl#mode", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
Append: "http://www.w3.org/ns/auth/acl#Append", |
||||||
|
Control: "http://www.w3.org/ns/auth/acl#Control", |
||||||
|
Read: "http://www.w3.org/ns/auth/acl#Read", |
||||||
|
Write: "http://www.w3.org/ns/auth/acl#Write", |
||||||
|
origin: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/acl#origin", |
||||||
|
"@type": "@id", |
||||||
|
}, |
||||||
|
key: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/cert#key", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
modulus: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/cert#modulus", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
exponent: { |
||||||
|
"@id": "http://www.w3.org/ns/auth/cert#exponent", |
||||||
|
"@type": "http://www.w3.org/2001/XMLSchema#integer", |
||||||
|
}, |
||||||
|
inbox: { |
||||||
|
"@id": "http://www.w3.org/ns/ldp#inbox", |
||||||
|
"@type": "@id", |
||||||
|
}, |
||||||
|
preferencesFile: { |
||||||
|
"@id": "http://www.w3.org/ns/pim/space#preferencesFile", |
||||||
|
"@type": "@id", |
||||||
|
}, |
||||||
|
storage: { |
||||||
|
"@id": "http://www.w3.org/ns/pim/space#storage", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
account: { |
||||||
|
"@id": "http://www.w3.org/ns/solid/terms#account", |
||||||
|
"@type": "@id", |
||||||
|
}, |
||||||
|
privateTypeIndex: { |
||||||
|
"@id": "http://www.w3.org/ns/solid/terms#privateTypeIndex", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
publicTypeIndex: { |
||||||
|
"@id": "http://www.w3.org/ns/solid/terms#publicTypeIndex", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
knows: { |
||||||
|
"@id": "http://xmlns.com/foaf/0.1/knows", |
||||||
|
"@type": "@id", |
||||||
|
"@container": "@set", |
||||||
|
}, |
||||||
|
}; |
@ -0,0 +1,749 @@ |
|||||||
|
import { Schema } from "shexj"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* solidProfileSchema: ShexJ Schema for solidProfile |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
export const solidProfileSchema: Schema = { |
||||||
|
type: "Schema", |
||||||
|
shapes: [ |
||||||
|
{ |
||||||
|
id: "https://shaperepo.com/schemas/solidProfile#SolidProfileShape", |
||||||
|
type: "ShapeDecl", |
||||||
|
shapeExpr: { |
||||||
|
type: "Shape", |
||||||
|
expression: { |
||||||
|
type: "EachOf", |
||||||
|
expressions: [ |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
values: ["http://schema.org/Person"], |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "Defines the node as a Person (from Schema.org)", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
values: ["http://xmlns.com/foaf/0.1/Person"], |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "Defines the node as a Person (from foaf)", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#fn", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"The formatted name of a person. Example: John Smith", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://xmlns.com/foaf/0.1/name", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "An alternate way to define a person's name.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#hasAddress", |
||||||
|
valueExpr: |
||||||
|
"https://shaperepo.com/schemas/solidProfile#AddressShape", |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The person's street address.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#hasEmail", |
||||||
|
valueExpr: |
||||||
|
"https://shaperepo.com/schemas/solidProfile#EmailShape", |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The person's email.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#hasPhoto", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "A link to the person's photo", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://xmlns.com/foaf/0.1/img", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "Photo link but in string form", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#hasTelephone", |
||||||
|
valueExpr: |
||||||
|
"https://shaperepo.com/schemas/solidProfile#PhoneNumberShape", |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "Person's telephone number", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#phone", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"An alternative way to define a person's telephone number using a string", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#organization-name", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"The name of the organization with which the person is affiliated", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#role", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"The name of the person's role in their organization", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/acl#trustedApp", |
||||||
|
valueExpr: |
||||||
|
"https://shaperepo.com/schemas/solidProfile#TrustedAppShape", |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"A list of app origins that are trusted by this user", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/cert#key", |
||||||
|
valueExpr: |
||||||
|
"https://shaperepo.com/schemas/solidProfile#RSAPublicKeyShape", |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"A list of RSA public keys that are associated with private keys the user holds.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/ldp#inbox", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"The user's LDP inbox to which apps can post notifications", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/pim/space#preferencesFile", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The user's preferences", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/pim/space#storage", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"The location of a Solid storage server related to this WebId", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/solid/terms#account", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The user's account", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/solid/terms#privateTypeIndex", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"A registry of all types used on the user's Pod (for private access only)", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/solid/terms#publicTypeIndex", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"A registry of all types used on the user's Pod (for public access)", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://xmlns.com/foaf/0.1/knows", |
||||||
|
valueExpr: |
||||||
|
"https://shaperepo.com/schemas/solidProfile#SolidProfileShape", |
||||||
|
min: 0, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"A list of WebIds for all the people this user knows.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
extra: ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"], |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: "https://shaperepo.com/schemas/solidProfile#AddressShape", |
||||||
|
type: "ShapeDecl", |
||||||
|
shapeExpr: { |
||||||
|
type: "Shape", |
||||||
|
expression: { |
||||||
|
type: "EachOf", |
||||||
|
expressions: [ |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#country-name", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The name of the user's country of residence", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#locality", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"The name of the user's locality (City, Town etc.) of residence", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#postal-code", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The user's postal code", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#region", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"The name of the user's region (State, Province etc.) of residence", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#street-address", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The user's street address", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: "https://shaperepo.com/schemas/solidProfile#EmailShape", |
||||||
|
type: "ShapeDecl", |
||||||
|
shapeExpr: { |
||||||
|
type: "Shape", |
||||||
|
expression: { |
||||||
|
type: "EachOf", |
||||||
|
expressions: [ |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
values: [ |
||||||
|
"http://www.w3.org/2006/vcard/ns#Dom", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Home", |
||||||
|
"http://www.w3.org/2006/vcard/ns#ISDN", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Internet", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Intl", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Label", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Parcel", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Postal", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Pref", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Work", |
||||||
|
"http://www.w3.org/2006/vcard/ns#X400", |
||||||
|
], |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The type of email.", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#value", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"The value of an email as a mailto link (Example <mailto:jane@example.com>)", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
extra: ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"], |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: "https://shaperepo.com/schemas/solidProfile#PhoneNumberShape", |
||||||
|
type: "ShapeDecl", |
||||||
|
shapeExpr: { |
||||||
|
type: "Shape", |
||||||
|
expression: { |
||||||
|
type: "EachOf", |
||||||
|
expressions: [ |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
values: [ |
||||||
|
"http://www.w3.org/2006/vcard/ns#Dom", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Home", |
||||||
|
"http://www.w3.org/2006/vcard/ns#ISDN", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Internet", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Intl", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Label", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Parcel", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Postal", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Pref", |
||||||
|
"http://www.w3.org/2006/vcard/ns#Work", |
||||||
|
"http://www.w3.org/2006/vcard/ns#X400", |
||||||
|
], |
||||||
|
}, |
||||||
|
min: 0, |
||||||
|
max: 1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "They type of Phone Number", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/2006/vcard/ns#value", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: |
||||||
|
"The value of a phone number as a tel link (Example <tel:555-555-5555>)", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
extra: ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"], |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: "https://shaperepo.com/schemas/solidProfile#TrustedAppShape", |
||||||
|
type: "ShapeDecl", |
||||||
|
shapeExpr: { |
||||||
|
type: "Shape", |
||||||
|
expression: { |
||||||
|
type: "EachOf", |
||||||
|
expressions: [ |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/acl#mode", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
values: [ |
||||||
|
"http://www.w3.org/ns/auth/acl#Append", |
||||||
|
"http://www.w3.org/ns/auth/acl#Control", |
||||||
|
"http://www.w3.org/ns/auth/acl#Read", |
||||||
|
"http://www.w3.org/ns/auth/acl#Write", |
||||||
|
], |
||||||
|
}, |
||||||
|
min: 1, |
||||||
|
max: -1, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The level of access provided to this origin", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/acl#origin", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
nodeKind: "iri", |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "The app origin the user trusts", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: "https://shaperepo.com/schemas/solidProfile#RSAPublicKeyShape", |
||||||
|
type: "ShapeDecl", |
||||||
|
shapeExpr: { |
||||||
|
type: "Shape", |
||||||
|
expression: { |
||||||
|
type: "EachOf", |
||||||
|
expressions: [ |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/cert#modulus", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#string", |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "RSA Modulus", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
{ |
||||||
|
type: "TripleConstraint", |
||||||
|
predicate: "http://www.w3.org/ns/auth/cert#exponent", |
||||||
|
valueExpr: { |
||||||
|
type: "NodeConstraint", |
||||||
|
datatype: "http://www.w3.org/2001/XMLSchema#integer", |
||||||
|
}, |
||||||
|
annotations: [ |
||||||
|
{ |
||||||
|
type: "Annotation", |
||||||
|
predicate: "http://www.w3.org/2000/01/rdf-schema#comment", |
||||||
|
object: { |
||||||
|
value: "RSA Exponent", |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
], |
||||||
|
}; |
@ -0,0 +1,71 @@ |
|||||||
|
import { ShapeType } from "@ldo/ldo"; |
||||||
|
import { solidProfileSchema } from "./solidProfile.schema"; |
||||||
|
import { solidProfileContext } from "./solidProfile.context"; |
||||||
|
import { |
||||||
|
SolidProfileShape, |
||||||
|
AddressShape, |
||||||
|
EmailShape, |
||||||
|
PhoneNumberShape, |
||||||
|
TrustedAppShape, |
||||||
|
RSAPublicKeyShape, |
||||||
|
} from "./solidProfile.typings"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* LDO ShapeTypes solidProfile |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* SolidProfileShape ShapeType |
||||||
|
*/ |
||||||
|
export const SolidProfileShapeShapeType: ShapeType<SolidProfileShape> = { |
||||||
|
schema: solidProfileSchema, |
||||||
|
shape: "https://shaperepo.com/schemas/solidProfile#SolidProfileShape", |
||||||
|
context: solidProfileContext, |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* AddressShape ShapeType |
||||||
|
*/ |
||||||
|
export const AddressShapeShapeType: ShapeType<AddressShape> = { |
||||||
|
schema: solidProfileSchema, |
||||||
|
shape: "https://shaperepo.com/schemas/solidProfile#AddressShape", |
||||||
|
context: solidProfileContext, |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* EmailShape ShapeType |
||||||
|
*/ |
||||||
|
export const EmailShapeShapeType: ShapeType<EmailShape> = { |
||||||
|
schema: solidProfileSchema, |
||||||
|
shape: "https://shaperepo.com/schemas/solidProfile#EmailShape", |
||||||
|
context: solidProfileContext, |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* PhoneNumberShape ShapeType |
||||||
|
*/ |
||||||
|
export const PhoneNumberShapeShapeType: ShapeType<PhoneNumberShape> = { |
||||||
|
schema: solidProfileSchema, |
||||||
|
shape: "https://shaperepo.com/schemas/solidProfile#PhoneNumberShape", |
||||||
|
context: solidProfileContext, |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* TrustedAppShape ShapeType |
||||||
|
*/ |
||||||
|
export const TrustedAppShapeShapeType: ShapeType<TrustedAppShape> = { |
||||||
|
schema: solidProfileSchema, |
||||||
|
shape: "https://shaperepo.com/schemas/solidProfile#TrustedAppShape", |
||||||
|
context: solidProfileContext, |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* RSAPublicKeyShape ShapeType |
||||||
|
*/ |
||||||
|
export const RSAPublicKeyShapeShapeType: ShapeType<RSAPublicKeyShape> = { |
||||||
|
schema: solidProfileSchema, |
||||||
|
shape: "https://shaperepo.com/schemas/solidProfile#RSAPublicKeyShape", |
||||||
|
context: solidProfileContext, |
||||||
|
}; |
@ -0,0 +1,293 @@ |
|||||||
|
import { ContextDefinition } from "jsonld"; |
||||||
|
|
||||||
|
/** |
||||||
|
* ============================================================================= |
||||||
|
* Typescript Typings for solidProfile |
||||||
|
* ============================================================================= |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* SolidProfileShape Type |
||||||
|
*/ |
||||||
|
export interface SolidProfileShape { |
||||||
|
"@id"?: string; |
||||||
|
"@context"?: ContextDefinition; |
||||||
|
/** |
||||||
|
* Defines the node as a Person (from Schema.org) | Defines the node as a Person (from foaf) |
||||||
|
*/ |
||||||
|
type: ( |
||||||
|
| { |
||||||
|
"@id": "Person"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Person2"; |
||||||
|
} |
||||||
|
)[]; |
||||||
|
/** |
||||||
|
* The formatted name of a person. Example: John Smith |
||||||
|
*/ |
||||||
|
fn?: string; |
||||||
|
/** |
||||||
|
* An alternate way to define a person's name. |
||||||
|
*/ |
||||||
|
name?: string; |
||||||
|
/** |
||||||
|
* The person's street address. |
||||||
|
*/ |
||||||
|
hasAddress?: AddressShape[]; |
||||||
|
/** |
||||||
|
* The person's email. |
||||||
|
*/ |
||||||
|
hasEmail?: EmailShape[]; |
||||||
|
/** |
||||||
|
* A link to the person's photo |
||||||
|
*/ |
||||||
|
hasPhoto?: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* Photo link but in string form |
||||||
|
*/ |
||||||
|
img?: string; |
||||||
|
/** |
||||||
|
* Person's telephone number |
||||||
|
*/ |
||||||
|
hasTelephone?: PhoneNumberShape[]; |
||||||
|
/** |
||||||
|
* An alternative way to define a person's telephone number using a string |
||||||
|
*/ |
||||||
|
phone?: string; |
||||||
|
/** |
||||||
|
* The name of the organization with which the person is affiliated |
||||||
|
*/ |
||||||
|
organizationName?: string; |
||||||
|
/** |
||||||
|
* The name of the person's role in their organization |
||||||
|
*/ |
||||||
|
role?: string; |
||||||
|
/** |
||||||
|
* A list of app origins that are trusted by this user |
||||||
|
*/ |
||||||
|
trustedApp?: TrustedAppShape[]; |
||||||
|
/** |
||||||
|
* A list of RSA public keys that are associated with private keys the user holds. |
||||||
|
*/ |
||||||
|
key?: RSAPublicKeyShape[]; |
||||||
|
/** |
||||||
|
* The user's LDP inbox to which apps can post notifications |
||||||
|
*/ |
||||||
|
inbox: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* The user's preferences |
||||||
|
*/ |
||||||
|
preferencesFile?: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* The location of a Solid storage server related to this WebId |
||||||
|
*/ |
||||||
|
storage?: { |
||||||
|
"@id": string; |
||||||
|
}[]; |
||||||
|
/** |
||||||
|
* The user's account |
||||||
|
*/ |
||||||
|
account?: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* A registry of all types used on the user's Pod (for private access only) |
||||||
|
*/ |
||||||
|
privateTypeIndex?: { |
||||||
|
"@id": string; |
||||||
|
}[]; |
||||||
|
/** |
||||||
|
* A registry of all types used on the user's Pod (for public access) |
||||||
|
*/ |
||||||
|
publicTypeIndex?: { |
||||||
|
"@id": string; |
||||||
|
}[]; |
||||||
|
/** |
||||||
|
* A list of WebIds for all the people this user knows. |
||||||
|
*/ |
||||||
|
knows?: SolidProfileShape[]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* AddressShape Type |
||||||
|
*/ |
||||||
|
export interface AddressShape { |
||||||
|
"@id"?: string; |
||||||
|
"@context"?: ContextDefinition; |
||||||
|
/** |
||||||
|
* The name of the user's country of residence |
||||||
|
*/ |
||||||
|
countryName?: string; |
||||||
|
/** |
||||||
|
* The name of the user's locality (City, Town etc.) of residence |
||||||
|
*/ |
||||||
|
locality?: string; |
||||||
|
/** |
||||||
|
* The user's postal code |
||||||
|
*/ |
||||||
|
postalCode?: string; |
||||||
|
/** |
||||||
|
* The name of the user's region (State, Province etc.) of residence |
||||||
|
*/ |
||||||
|
region?: string; |
||||||
|
/** |
||||||
|
* The user's street address |
||||||
|
*/ |
||||||
|
streetAddress?: string; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* EmailShape Type |
||||||
|
*/ |
||||||
|
export interface EmailShape { |
||||||
|
"@id"?: string; |
||||||
|
"@context"?: ContextDefinition; |
||||||
|
/** |
||||||
|
* The type of email. |
||||||
|
*/ |
||||||
|
type?: |
||||||
|
| { |
||||||
|
"@id": "Dom"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Home"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "ISDN"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Internet"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Intl"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Label"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Parcel"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Postal"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Pref"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Work"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "X400"; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* The value of an email as a mailto link (Example <mailto:jane@example.com>) |
||||||
|
*/ |
||||||
|
value: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* PhoneNumberShape Type |
||||||
|
*/ |
||||||
|
export interface PhoneNumberShape { |
||||||
|
"@id"?: string; |
||||||
|
"@context"?: ContextDefinition; |
||||||
|
/** |
||||||
|
* They type of Phone Number |
||||||
|
*/ |
||||||
|
type?: |
||||||
|
| { |
||||||
|
"@id": "Dom"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Home"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "ISDN"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Internet"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Intl"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Label"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Parcel"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Postal"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Pref"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Work"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "X400"; |
||||||
|
}; |
||||||
|
/** |
||||||
|
* The value of a phone number as a tel link (Example <tel:555-555-5555>) |
||||||
|
*/ |
||||||
|
value: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* TrustedAppShape Type |
||||||
|
*/ |
||||||
|
export interface TrustedAppShape { |
||||||
|
"@id"?: string; |
||||||
|
"@context"?: ContextDefinition; |
||||||
|
/** |
||||||
|
* The level of access provided to this origin |
||||||
|
*/ |
||||||
|
mode: ( |
||||||
|
| { |
||||||
|
"@id": "Append"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Control"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Read"; |
||||||
|
} |
||||||
|
| { |
||||||
|
"@id": "Write"; |
||||||
|
} |
||||||
|
)[]; |
||||||
|
/** |
||||||
|
* The app origin the user trusts |
||||||
|
*/ |
||||||
|
origin: { |
||||||
|
"@id": string; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* RSAPublicKeyShape Type |
||||||
|
*/ |
||||||
|
export interface RSAPublicKeyShape { |
||||||
|
"@id"?: string; |
||||||
|
"@context"?: ContextDefinition; |
||||||
|
/** |
||||||
|
* RSA Modulus |
||||||
|
*/ |
||||||
|
modulus: string; |
||||||
|
/** |
||||||
|
* RSA Exponent |
||||||
|
*/ |
||||||
|
exponent: number; |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> |
||||||
|
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> |
||||||
|
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> |
||||||
|
PREFIX ex: <https://example.com/> |
||||||
|
BASE <http://schema.org/> |
||||||
|
|
||||||
|
ex:PostSh { |
||||||
|
a [<SocialMediaPosting> <CreativeWork> <Thing>] ; |
||||||
|
<articleBody> xsd:string? |
||||||
|
// rdfs:label '''articleBody''' |
||||||
|
// rdfs:comment '''The actual body of the article. ''' ; |
||||||
|
<uploadDate> xsd:date |
||||||
|
// rdfs:label '''uploadDate''' |
||||||
|
// rdfs:comment '''Date when this media object was uploaded to this site.''' ; |
||||||
|
<image> IRI ? |
||||||
|
// rdfs:label '''image''' |
||||||
|
// rdfs:comment '''A media object that encodes this CreativeWork. This property is a synonym for encoding.''' ; |
||||||
|
<publisher> IRI |
||||||
|
// rdfs:label '''publisher''' |
||||||
|
// rdfs:comment '''The publisher of the creative work.''' ; |
||||||
|
} |
||||||
|
// rdfs:label '''SocialMediaPost''' |
||||||
|
// rdfs:comment '''A post to a social media platform, including blog posts, tweets, Facebook posts, etc.''' |
@ -0,0 +1,121 @@ |
|||||||
|
PREFIX srs: <https://shaperepo.com/schemas/solidProfile#> |
||||||
|
PREFIX foaf: <http://xmlns.com/foaf/0.1/> |
||||||
|
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> |
||||||
|
PREFIX schem: <http://schema.org/> |
||||||
|
PREFIX vcard: <http://www.w3.org/2006/vcard/ns#> |
||||||
|
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> |
||||||
|
PREFIX acl: <http://www.w3.org/ns/auth/acl#> |
||||||
|
PREFIX cert: <http://www.w3.org/ns/auth/cert#> |
||||||
|
PREFIX ldp: <http://www.w3.org/ns/ldp#> |
||||||
|
PREFIX sp: <http://www.w3.org/ns/pim/space#> |
||||||
|
PREFIX solid: <http://www.w3.org/ns/solid/terms#> |
||||||
|
|
||||||
|
srs:SolidProfileShape EXTRA a { |
||||||
|
a [ schem:Person ] |
||||||
|
// rdfs:comment "Defines the node as a Person (from Schema.org)" ; |
||||||
|
a [ foaf:Person ] |
||||||
|
// rdfs:comment "Defines the node as a Person (from foaf)" ; |
||||||
|
vcard:fn xsd:string ? |
||||||
|
// rdfs:comment "The formatted name of a person. Example: John Smith" ; |
||||||
|
foaf:name xsd:string ? |
||||||
|
// rdfs:comment "An alternate way to define a person's name." ; |
||||||
|
vcard:hasAddress @srs:AddressShape * |
||||||
|
// rdfs:comment "The person's street address." ; |
||||||
|
vcard:hasEmail @srs:EmailShape * |
||||||
|
// rdfs:comment "The person's email." ; |
||||||
|
vcard:hasPhoto IRI ? |
||||||
|
// rdfs:comment "A link to the person's photo" ; |
||||||
|
foaf:img xsd:string ? |
||||||
|
// rdfs:comment "Photo link but in string form" ; |
||||||
|
vcard:hasTelephone @srs:PhoneNumberShape * |
||||||
|
// rdfs:comment "Person's telephone number" ; |
||||||
|
vcard:phone xsd:string ? |
||||||
|
// rdfs:comment "An alternative way to define a person's telephone number using a string" ; |
||||||
|
vcard:organization-name xsd:string ? |
||||||
|
// rdfs:comment "The name of the organization with which the person is affiliated" ; |
||||||
|
vcard:role xsd:string ? |
||||||
|
// rdfs:comment "The name of the person's role in their organization" ; |
||||||
|
acl:trustedApp @srs:TrustedAppShape * |
||||||
|
// rdfs:comment "A list of app origins that are trusted by this user" ; |
||||||
|
cert:key @srs:RSAPublicKeyShape * |
||||||
|
// rdfs:comment "A list of RSA public keys that are associated with private keys the user holds." ; |
||||||
|
ldp:inbox IRI |
||||||
|
// rdfs:comment "The user's LDP inbox to which apps can post notifications" ; |
||||||
|
sp:preferencesFile IRI ? |
||||||
|
// rdfs:comment "The user's preferences" ; |
||||||
|
sp:storage IRI * |
||||||
|
// rdfs:comment "The location of a Solid storage server related to this WebId" ; |
||||||
|
solid:account IRI ? |
||||||
|
// rdfs:comment "The user's account" ; |
||||||
|
solid:privateTypeIndex IRI * |
||||||
|
// rdfs:comment "A registry of all types used on the user's Pod (for private access only)" ; |
||||||
|
solid:publicTypeIndex IRI * |
||||||
|
// rdfs:comment "A registry of all types used on the user's Pod (for public access)" ; |
||||||
|
foaf:knows @srs:SolidProfileShape * |
||||||
|
// rdfs:comment "A list of WebIds for all the people this user knows." ; |
||||||
|
} |
||||||
|
|
||||||
|
srs:AddressShape { |
||||||
|
vcard:country-name xsd:string ? |
||||||
|
// rdfs:comment "The name of the user's country of residence" ; |
||||||
|
vcard:locality xsd:string ? |
||||||
|
// rdfs:comment "The name of the user's locality (City, Town etc.) of residence" ; |
||||||
|
vcard:postal-code xsd:string ? |
||||||
|
// rdfs:comment "The user's postal code" ; |
||||||
|
vcard:region xsd:string ? |
||||||
|
// rdfs:comment "The name of the user's region (State, Province etc.) of residence" ; |
||||||
|
vcard:street-address xsd:string ? |
||||||
|
// rdfs:comment "The user's street address" ; |
||||||
|
} |
||||||
|
|
||||||
|
srs:EmailShape EXTRA a { |
||||||
|
a [ |
||||||
|
vcard:Dom |
||||||
|
vcard:Home |
||||||
|
vcard:ISDN |
||||||
|
vcard:Internet |
||||||
|
vcard:Intl |
||||||
|
vcard:Label |
||||||
|
vcard:Parcel |
||||||
|
vcard:Postal |
||||||
|
vcard:Pref |
||||||
|
vcard:Work |
||||||
|
vcard:X400 |
||||||
|
] ? |
||||||
|
// rdfs:comment "The type of email." ; |
||||||
|
vcard:value IRI |
||||||
|
// rdfs:comment "The value of an email as a mailto link (Example <mailto:jane@example.com>)" ; |
||||||
|
} |
||||||
|
|
||||||
|
srs:PhoneNumberShape EXTRA a { |
||||||
|
a [ |
||||||
|
vcard:Dom |
||||||
|
vcard:Home |
||||||
|
vcard:ISDN |
||||||
|
vcard:Internet |
||||||
|
vcard:Intl |
||||||
|
vcard:Label |
||||||
|
vcard:Parcel |
||||||
|
vcard:Postal |
||||||
|
vcard:Pref |
||||||
|
vcard:Work |
||||||
|
vcard:X400 |
||||||
|
] ? |
||||||
|
// rdfs:comment "They type of Phone Number" ; |
||||||
|
vcard:value IRI |
||||||
|
// rdfs:comment "The value of a phone number as a tel link (Example <tel:555-555-5555>)" ; |
||||||
|
} |
||||||
|
|
||||||
|
srs:TrustedAppShape { |
||||||
|
acl:mode [acl:Append acl:Control acl:Read acl:Write] + |
||||||
|
// rdfs:comment "The level of access provided to this origin" ; |
||||||
|
acl:origin IRI |
||||||
|
// rdfs:comment "The app origin the user trusts" |
||||||
|
} |
||||||
|
|
||||||
|
srs:RSAPublicKeyShape { |
||||||
|
cert:modulus xsd:string |
||||||
|
// rdfs:comment "RSA Modulus" ; |
||||||
|
cert:exponent xsd:integer |
||||||
|
// rdfs:comment "RSA Exponent" ; |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
import type { FunctionComponent } from "react"; |
||||||
|
import React from "react"; |
||||||
|
import { Router } from "./Layout"; |
||||||
|
import { BrowserSolidLdoProvider } from "@ldo/solid-react"; |
||||||
|
|
||||||
|
const ProfileApp: FunctionComponent = () => { |
||||||
|
return ( |
||||||
|
<BrowserSolidLdoProvider> |
||||||
|
<Router /> |
||||||
|
</BrowserSolidLdoProvider> |
||||||
|
); |
||||||
|
}; |
||||||
|
export default ProfileApp; |
@ -0,0 +1,65 @@ |
|||||||
|
import type { FunctionComponent } from "react"; |
||||||
|
import React, { useCallback } from "react"; |
||||||
|
import { |
||||||
|
BrowserSolidLdoProvider, |
||||||
|
useResource, |
||||||
|
useSolidAuth, |
||||||
|
useSubject, |
||||||
|
} from "@ldo/solid-react"; |
||||||
|
import { SolidProfileShapeShapeType } from "./.ldo/solidProfile.shapeTypes"; |
||||||
|
import { changeData, commitData } from "@ldo/solid"; |
||||||
|
|
||||||
|
// The base component for the app
|
||||||
|
const App: FunctionComponent = () => { |
||||||
|
return ( |
||||||
|
/* The application should be surrounded with the BrowserSolidLdoProvider |
||||||
|
this will set up all the underlying infrastructure for the application */ |
||||||
|
<BrowserSolidLdoProvider> |
||||||
|
<Login /> |
||||||
|
</BrowserSolidLdoProvider> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
// A component that handles login
|
||||||
|
const Login: FunctionComponent = () => { |
||||||
|
// Get login information using the "useSolidAuth" hook
|
||||||
|
const { login, logout, session } = useSolidAuth(); |
||||||
|
|
||||||
|
const onLogin = useCallback(() => { |
||||||
|
const issuer = prompt("What is your Solid IDP?"); |
||||||
|
// Call the "login" function to initiate login
|
||||||
|
if (issuer) login(issuer); |
||||||
|
}, []); |
||||||
|
|
||||||
|
// You can use session.isLoggedIn to check if the user is logged in
|
||||||
|
if (session.isLoggedIn) { |
||||||
|
return ( |
||||||
|
<div> |
||||||
|
{/* Get the user's webId from session.webId */} |
||||||
|
<p>Logged in as {session.webId}</p> |
||||||
|
{/* Use the logout function to log out */} |
||||||
|
<button onClick={logout}>Log Out</button> |
||||||
|
<Profile /> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
return <button onClick={onLogin}>Log In</button>; |
||||||
|
}; |
||||||
|
|
||||||
|
const Profile: FunctionComponent = () => { |
||||||
|
const { session } = useSolidAuth(); |
||||||
|
const resource = useResource(session.webId); |
||||||
|
const profile = useSubject(SolidProfileShapeShapeType, session.webId); |
||||||
|
|
||||||
|
const onNameChange = useCallback(async (e) => { |
||||||
|
// Ensure that the
|
||||||
|
if (!profile || !resource) return; |
||||||
|
const cProfile = changeData(profile, resource); |
||||||
|
cProfile.name = e.target.value; |
||||||
|
await commitData(cProfile); |
||||||
|
}, []); |
||||||
|
|
||||||
|
return <input type="text" value={profile?.name} onChange={onNameChange} />; |
||||||
|
}; |
||||||
|
|
||||||
|
export default App; |
@ -0,0 +1,54 @@ |
|||||||
|
import { useState } from "react"; |
||||||
|
import type { FunctionComponent } from "react"; |
||||||
|
import React from "react"; |
||||||
|
import { useResource, useSolidAuth, useSubject } from "@ldo/solid-react"; |
||||||
|
import { SolidProfileShapeShapeType } from "./.ldo/solidProfile.shapeTypes"; |
||||||
|
import { Link } from "react-router-dom"; |
||||||
|
|
||||||
|
const DEFAULT_ISSUER = "https://solidweb.me"; |
||||||
|
|
||||||
|
export const LoggedInHeader: FunctionComponent<{ webId: string }> = ({ |
||||||
|
webId, |
||||||
|
}) => { |
||||||
|
const webIdResource = useResource(webId); |
||||||
|
const profile = useSubject(SolidProfileShapeShapeType, webId); |
||||||
|
const { logout } = useSolidAuth(); |
||||||
|
return ( |
||||||
|
<> |
||||||
|
<span> |
||||||
|
Logged in as {webId}. Welcome{" "} |
||||||
|
{webIdResource.isReading() ? "LOADING NAME" : profile.fn} |
||||||
|
</span> |
||||||
|
<button onClick={logout}>Log Out</button> |
||||||
|
</> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export const Header: FunctionComponent = () => { |
||||||
|
const [issuer, setIssuer] = useState(DEFAULT_ISSUER); |
||||||
|
const { login, signUp, session } = useSolidAuth(); |
||||||
|
return ( |
||||||
|
<header> |
||||||
|
<div style={{ display: "flex" }}> |
||||||
|
{session.isLoggedIn ? ( |
||||||
|
<LoggedInHeader webId={session.webId!} /> |
||||||
|
) : ( |
||||||
|
<> |
||||||
|
<input |
||||||
|
type="text" |
||||||
|
value={issuer} |
||||||
|
onChange={(e) => setIssuer(e.target.value)} |
||||||
|
/> |
||||||
|
<button onClick={() => login(issuer)}>Log In</button> |
||||||
|
<button onClick={() => signUp(issuer)}>Sign Up</button> |
||||||
|
</> |
||||||
|
)} |
||||||
|
</div> |
||||||
|
<p> |
||||||
|
<Link to="/">Blog</Link> |
||||||
|
{" "} |
||||||
|
<Link to="/profile">Profile</Link> |
||||||
|
</p> |
||||||
|
</header> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,50 @@ |
|||||||
|
import { useSolidAuth } from "@ldo/solid-react"; |
||||||
|
import React, { Fragment } from "react"; |
||||||
|
import type { FunctionComponent } from "react"; |
||||||
|
import { createBrowserRouter, Outlet, RouterProvider } from "react-router-dom"; |
||||||
|
import { Blog } from "./blog/Blog"; |
||||||
|
import { PostPage } from "./post/PostPage"; |
||||||
|
import { Header } from "./Header"; |
||||||
|
import { MainContainerProvider } from "./MainContainerProvider"; |
||||||
|
import { Profile } from "./profile/Profile"; |
||||||
|
|
||||||
|
export const Layout: FunctionComponent = () => { |
||||||
|
const { session } = useSolidAuth(); |
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Header /> |
||||||
|
<hr /> |
||||||
|
<MainContainerProvider> |
||||||
|
{session.isLoggedIn ? <Outlet /> : <Fragment />} |
||||||
|
</MainContainerProvider> |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
const router = createBrowserRouter([ |
||||||
|
{ |
||||||
|
element: <Layout />, |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
path: "/", |
||||||
|
element: <Blog />, |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: "/media/:uri", |
||||||
|
element: <PostPage />, |
||||||
|
}, |
||||||
|
{ |
||||||
|
path: "/profile", |
||||||
|
element: <Profile />, |
||||||
|
}, |
||||||
|
], |
||||||
|
}, |
||||||
|
]); |
||||||
|
|
||||||
|
export const Router: FunctionComponent = () => { |
||||||
|
const { ranInitialAuthCheck } = useSolidAuth(); |
||||||
|
if (!ranInitialAuthCheck) { |
||||||
|
return <p>Loading</p>; |
||||||
|
} |
||||||
|
return <RouterProvider router={router} />; |
||||||
|
}; |
@ -0,0 +1,73 @@ |
|||||||
|
import React, { useState, useEffect, createContext } from "react"; |
||||||
|
import type { FunctionComponent, PropsWithChildren } from "react"; |
||||||
|
import type { Container, LeafUri } from "@ldo/solid"; |
||||||
|
import { useSolidAuth, useLdo, useResource } from "@ldo/solid-react"; |
||||||
|
|
||||||
|
export const MainContainerContext = createContext<Container | undefined>( |
||||||
|
undefined, |
||||||
|
); |
||||||
|
|
||||||
|
const MainContainerSubProvider: FunctionComponent< |
||||||
|
PropsWithChildren<{ uri?: string }> |
||||||
|
> = ({ uri, children }) => { |
||||||
|
const mainContainer = useResource(uri); |
||||||
|
return ( |
||||||
|
<MainContainerContext.Provider value={mainContainer as Container}> |
||||||
|
{children} |
||||||
|
</MainContainerContext.Provider> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export const MainContainerProvider: FunctionComponent<PropsWithChildren> = ({ |
||||||
|
children, |
||||||
|
}) => { |
||||||
|
const [mainContainer, setMainContainer] = useState<Container | undefined>(); |
||||||
|
const { session } = useSolidAuth(); |
||||||
|
const { getResource } = useLdo(); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (session.webId) { |
||||||
|
const webIdResource = getResource(session.webId as LeafUri); |
||||||
|
webIdResource.getRootContainer().then(async (rootContainer) => { |
||||||
|
if (rootContainer.isError) { |
||||||
|
alert(rootContainer.message); |
||||||
|
return; |
||||||
|
} |
||||||
|
const mainContainer = getResource(`${rootContainer.uri}demo-react/`); |
||||||
|
setMainContainer(mainContainer); |
||||||
|
const createResult = await mainContainer.createIfAbsent(); |
||||||
|
// Only set the access rules if the create was a success.
|
||||||
|
if (createResult.type === "createSuccess") { |
||||||
|
await mainContainer.setWac({ |
||||||
|
public: { |
||||||
|
read: true, |
||||||
|
write: false, |
||||||
|
append: false, |
||||||
|
control: false, |
||||||
|
}, |
||||||
|
authenticated: { |
||||||
|
read: true, |
||||||
|
write: false, |
||||||
|
append: false, |
||||||
|
control: false, |
||||||
|
}, |
||||||
|
agent: { |
||||||
|
[session.webId!]: { |
||||||
|
read: true, |
||||||
|
write: true, |
||||||
|
append: true, |
||||||
|
control: true, |
||||||
|
}, |
||||||
|
}, |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}, [session.webId]); |
||||||
|
|
||||||
|
return ( |
||||||
|
<MainContainerSubProvider uri={mainContainer?.uri}> |
||||||
|
{children} |
||||||
|
</MainContainerSubProvider> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,30 @@ |
|||||||
|
import React, { Fragment, useContext } from "react"; |
||||||
|
import type { FunctionComponent } from "react"; |
||||||
|
import { MainContainerContext } from "../MainContainerProvider"; |
||||||
|
import { Post } from "../post/Post"; |
||||||
|
import { MakePost } from "./MakePost"; |
||||||
|
|
||||||
|
export const Blog: FunctionComponent = () => { |
||||||
|
const mainContainer = useContext(MainContainerContext); |
||||||
|
if (mainContainer === undefined) { |
||||||
|
return <p>Loading...</p>; |
||||||
|
} |
||||||
|
if (mainContainer.isDoingInitialFetch()) { |
||||||
|
return <p>Loading Blob</p>; |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<div> |
||||||
|
<MakePost mainContainer={mainContainer} /> |
||||||
|
</div> |
||||||
|
<hr /> |
||||||
|
{mainContainer.children().map((child) => ( |
||||||
|
<Fragment key={child.uri}> |
||||||
|
<Post uri={child.uri} /> |
||||||
|
<hr /> |
||||||
|
</Fragment> |
||||||
|
))} |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,92 @@ |
|||||||
|
import React, { useCallback, useState, useRef } from "react"; |
||||||
|
import type { FunctionComponent, FormEvent } from "react"; |
||||||
|
import type { Container, Leaf, LeafUri } from "@ldo/solid"; |
||||||
|
import { v4 } from "uuid"; |
||||||
|
import { useLdo, useSolidAuth } from "@ldo/solid-react"; |
||||||
|
import { PostShShapeType } from "../.ldo/post.shapeTypes"; |
||||||
|
|
||||||
|
export const MakePost: FunctionComponent<{ mainContainer: Container }> = ({ |
||||||
|
mainContainer, |
||||||
|
}) => { |
||||||
|
const [message, setMessage] = useState(""); |
||||||
|
const [selectedFile, setSelectedFile] = useState<File | undefined>(); |
||||||
|
const fileInputRef = useRef<HTMLInputElement | null>(null); |
||||||
|
const { createData, commitData } = useLdo(); |
||||||
|
const { session } = useSolidAuth(); |
||||||
|
const onSubmit = useCallback( |
||||||
|
async (e: FormEvent<HTMLFormElement>) => { |
||||||
|
e.preventDefault(); |
||||||
|
|
||||||
|
// Create the container file
|
||||||
|
const mediaContainerResult = await mainContainer.createChildAndOverwrite( |
||||||
|
`${v4()}/`, |
||||||
|
); |
||||||
|
if (mediaContainerResult.isError) { |
||||||
|
alert(mediaContainerResult.message); |
||||||
|
return; |
||||||
|
} |
||||||
|
const mediaContainer = mediaContainerResult.resource; |
||||||
|
|
||||||
|
// Upload Image
|
||||||
|
let uploadedImage: Leaf | undefined; |
||||||
|
if (selectedFile) { |
||||||
|
const result = await mediaContainer.uploadChildAndOverwrite( |
||||||
|
selectedFile.name as LeafUri, |
||||||
|
selectedFile, |
||||||
|
selectedFile.type, |
||||||
|
); |
||||||
|
if (result.isError) { |
||||||
|
alert(result.message); |
||||||
|
await mediaContainer.delete(); |
||||||
|
return; |
||||||
|
} |
||||||
|
uploadedImage = result.resource; |
||||||
|
} |
||||||
|
|
||||||
|
// Create Post
|
||||||
|
const indexResource = mediaContainer.child("index.ttl"); |
||||||
|
const post = createData( |
||||||
|
PostShShapeType, |
||||||
|
indexResource.uri, |
||||||
|
indexResource, |
||||||
|
); |
||||||
|
post.articleBody = message; |
||||||
|
if (uploadedImage) { |
||||||
|
post.image = { "@id": uploadedImage.uri }; |
||||||
|
} |
||||||
|
if (session.webId) { |
||||||
|
post.publisher = { "@id": session.webId }; |
||||||
|
} |
||||||
|
post.type = { "@id": "SocialMediaPosting" }; |
||||||
|
post.uploadDate = new Date().toISOString(); |
||||||
|
const result = await commitData(post); |
||||||
|
if (result.isError) { |
||||||
|
alert(result.message); |
||||||
|
} |
||||||
|
|
||||||
|
// Clear the UI after Upload
|
||||||
|
setMessage(""); |
||||||
|
setSelectedFile(undefined); |
||||||
|
if (fileInputRef.current) fileInputRef.current.value = ""; |
||||||
|
}, |
||||||
|
[message, selectedFile, session.webId], |
||||||
|
); |
||||||
|
|
||||||
|
return ( |
||||||
|
<form onSubmit={onSubmit}> |
||||||
|
<input |
||||||
|
type="text" |
||||||
|
placeholder="Make a Post" |
||||||
|
value={message} |
||||||
|
onChange={(e) => setMessage(e.target.value)} |
||||||
|
/> |
||||||
|
<input |
||||||
|
type="file" |
||||||
|
accept="image/*" |
||||||
|
ref={fileInputRef} |
||||||
|
onChange={(e) => setSelectedFile(e.target.files?.[0])} |
||||||
|
/> |
||||||
|
<input type="submit" value="Post" /> |
||||||
|
</form> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,8 @@ |
|||||||
|
import React from "react"; |
||||||
|
import ReactDOM from "react-dom/client"; |
||||||
|
import App from "./App"; |
||||||
|
|
||||||
|
const root = ReactDOM.createRoot( |
||||||
|
document.getElementById("root") as HTMLElement, |
||||||
|
); |
||||||
|
root.render(<App />); |
@ -0,0 +1,42 @@ |
|||||||
|
import React, { useCallback } from "react"; |
||||||
|
import type { FunctionComponent } from "react"; |
||||||
|
import { useLdo, useResource, useSubject } from "@ldo/solid-react"; |
||||||
|
import { PostShShapeType } from "../.ldo/post.shapeTypes"; |
||||||
|
import { useNavigate } from "react-router-dom"; |
||||||
|
import { PostedBy } from "./PostedBy"; |
||||||
|
|
||||||
|
export const Post: FunctionComponent<{ uri: string }> = ({ uri }) => { |
||||||
|
const navigate = useNavigate(); |
||||||
|
const mediaResource = useResource(`${uri}index.ttl`); |
||||||
|
const post = useSubject(PostShShapeType, mediaResource.uri); |
||||||
|
const { getResource } = useLdo(); |
||||||
|
const deletePost = useCallback(async () => { |
||||||
|
const postContainer = getResource(uri); |
||||||
|
const result = await postContainer.delete(); |
||||||
|
if (result.isError) { |
||||||
|
alert(result.message); |
||||||
|
} |
||||||
|
}, [uri]); |
||||||
|
|
||||||
|
if (mediaResource.isReading()) { |
||||||
|
return <p>Loading Post...</p>; |
||||||
|
} else if (mediaResource.status.isError) { |
||||||
|
return <p>Error: {mediaResource.status.message}</p>; |
||||||
|
} else if (mediaResource.isAbsent()) { |
||||||
|
return <p>Post does not exist.</p>; |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
{post.publisher?.["@id"] && <PostedBy webId={post.publisher["@id"]} />} |
||||||
|
<div |
||||||
|
onClick={() => navigate(`/media/${encodeURIComponent(uri)}`)} |
||||||
|
style={{ cursor: "pointer" }} |
||||||
|
> |
||||||
|
{post.articleBody && <p>{post.articleBody}</p>} |
||||||
|
{post.image && <img src={post.image["@id"]} style={{ height: 300 }} />} |
||||||
|
</div> |
||||||
|
<button onClick={deletePost}>Delete Post</button> |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,16 @@ |
|||||||
|
import React from "react"; |
||||||
|
import type { FunctionComponent } from "react"; |
||||||
|
import { useNavigate, useParams } from "react-router-dom"; |
||||||
|
import { Post } from "./Post"; |
||||||
|
|
||||||
|
export const PostPage: FunctionComponent = () => { |
||||||
|
const navigate = useNavigate(); |
||||||
|
const { uri } = useParams(); |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<button onClick={() => navigate("/")}>Back to Feed</button> |
||||||
|
{uri ? <Post uri={uri} /> : <p>No URI Present</p>} |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,16 @@ |
|||||||
|
import type { FunctionComponent } from "react"; |
||||||
|
import React from "react"; |
||||||
|
import { useResource, useSubject } from "@ldo/solid-react"; |
||||||
|
import { SolidProfileShapeShapeType } from "../.ldo/solidProfile.shapeTypes"; |
||||||
|
|
||||||
|
export const PostedBy: FunctionComponent<{ webId: string }> = ({ webId }) => { |
||||||
|
const webIdResource = useResource(webId); |
||||||
|
const profile = useSubject(SolidProfileShapeShapeType, webId); |
||||||
|
|
||||||
|
if (webIdResource.isReading()) { |
||||||
|
return <p>Loading Profile...</p>; |
||||||
|
} else if (webIdResource.status.isError) { |
||||||
|
return <p>Error: {webIdResource.status.message}</p>; |
||||||
|
} |
||||||
|
return <p>Posted By: {profile.fn}</p>; |
||||||
|
}; |
@ -0,0 +1,34 @@ |
|||||||
|
import { |
||||||
|
useLdo, |
||||||
|
useResource, |
||||||
|
useSolidAuth, |
||||||
|
useSubject, |
||||||
|
} from "@ldo/solid-react"; |
||||||
|
import type { ChangeEvent } from "react"; |
||||||
|
import React, { useCallback, type FunctionComponent } from "react"; |
||||||
|
import { SolidProfileShapeShapeType } from "../.ldo/solidProfile.shapeTypes"; |
||||||
|
|
||||||
|
export const Profile: FunctionComponent = () => { |
||||||
|
const { session } = useSolidAuth(); |
||||||
|
const profile = useSubject(SolidProfileShapeShapeType, session.webId); |
||||||
|
const webIdResource = useResource(session.webId); |
||||||
|
const { changeData, commitData } = useLdo(); |
||||||
|
|
||||||
|
const onNameChange = useCallback( |
||||||
|
async (e: ChangeEvent<HTMLInputElement>) => { |
||||||
|
if (profile && webIdResource) { |
||||||
|
const cProfile = changeData(profile, webIdResource); |
||||||
|
cProfile.fn = e.target.value; |
||||||
|
await commitData(cProfile); |
||||||
|
} |
||||||
|
}, |
||||||
|
[profile, webIdResource], |
||||||
|
); |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<label>Name</label> |
||||||
|
<input type="text" value={profile?.fn || ""} onChange={onNameChange} /> |
||||||
|
</> |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,20 @@ |
|||||||
|
{ |
||||||
|
"extends": "../../tsconfig.json", |
||||||
|
"compilerOptions": { |
||||||
|
"outDir": "./dist", |
||||||
|
"lib": ["dom", "dom.iterable", "esnext"], |
||||||
|
"allowJs": true, |
||||||
|
"skipLibCheck": true, |
||||||
|
"allowSyntheticDefaultImports": true, |
||||||
|
"forceConsistentCasingInFileNames": true, |
||||||
|
"noFallthroughCasesInSwitch": true, |
||||||
|
"moduleResolution": "node", |
||||||
|
"resolveJsonModule": true, |
||||||
|
"isolatedModules": true, |
||||||
|
"noEmit": true, |
||||||
|
"jsx": "react-jsx" |
||||||
|
}, |
||||||
|
"include": [ |
||||||
|
"./src" |
||||||
|
] |
||||||
|
} |
Loading…
Reference in new issue