Last active
September 14, 2023 14:06
-
-
Save angiejones/943a2233ba37c26dcc7e15cb88843621 to your computer and use it in GitHub Desktop.
Completed code from Web5.js Workshop (v0.7.11)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Web5} from '@tbd54566975/web5'; | |
const {web5, did: userDid} = await Web5.connect(); | |
console.log(userDid); | |
await web5.did.resolve(userDid).then(console.log); | |
//Schema we'll use for Book Reviews | |
const schema = { | |
"context": 'https://schema.org/', | |
"type": 'Review', | |
get uri() { return this.context + this.type; } | |
} | |
//Book Reviews | |
let reviews = [ | |
{ | |
"@context": schema.context, | |
"@type": schema.type, | |
"itemReviewed": { | |
"@type": "Book", | |
"name": "The Great Gatsby", | |
"author": { | |
"@type": "Person", | |
"name": "F. Scott Fitzgerald" | |
}, | |
"datePublished": "1925", | |
"genre": "Fiction" | |
}, | |
"author": { | |
"@type": "Person", | |
"did": userDid | |
}, | |
"datePublished": "2023-07-17", | |
"reviewRating": { | |
"@type": "Rating", | |
"ratingValue": "4.5" | |
}, | |
"reviewBody": "A classic novel with timeless themes and memorable characters. Fitzgerald's prose is simply enchanting." | |
}, | |
{ | |
"@context": schema.context, | |
"@type": schema.type, | |
"itemReviewed": { | |
"@type": "Book", | |
"name": "To Kill a Mockingbird", | |
"author": { | |
"@type": "Person", | |
"name": "Harper Lee" | |
}, | |
"datePublished": "1960", | |
"genre": "Fiction" | |
}, | |
"author": { | |
"@type": "Person", | |
"did": userDid | |
}, | |
"datePublished": "2023-07-17", | |
"reviewRating": { | |
"@type": "Rating", | |
"ratingValue": "5.0" | |
}, | |
"reviewBody": "A powerful exploration of morality, justice, and the human condition. Truly a must-read." | |
}, | |
{ | |
"@context": schema.context, | |
"@type": schema.type, | |
"itemReviewed": { | |
"@type": "Book", | |
"name": "1984", | |
"author": { | |
"@type": "Person", | |
"name": "George Orwell" | |
}, | |
"datePublished": "1949", | |
"genre": "Dystopian" | |
}, | |
"author": { | |
"@type": "Person", | |
"did": userDid | |
}, | |
"datePublished": "2023-07-18", | |
"reviewRating": { | |
"@type": "Rating", | |
"ratingValue": "4.7" | |
}, | |
"reviewBody": "A disturbing vision of a totalitarian future. Orwell's work is as relevant today as it was when it was first published." | |
}, | |
{ | |
"@context": schema.context, | |
"@type": schema.type, | |
"itemReviewed": { | |
"@type": "Book", | |
"name": "Brave New World", | |
"author": { | |
"@type": "Person", | |
"name": "Aldous Huxley" | |
}, | |
"datePublished": "1932", | |
"genre": "Dystopian" | |
}, | |
"author": { | |
"@type": "Person", | |
"did": userDid | |
}, | |
"datePublished": "2023-07-19", | |
"reviewRating": { | |
"@type": "Rating", | |
"ratingValue": "4.8" | |
}, | |
"reviewBody": "A deeply disturbing yet essential read. Huxley's vision of a future driven by technology and hedonism serves as a potent warning for society." | |
} | |
] | |
//Create book review (write record to DWN) | |
async function addReviews() { | |
for (const review of reviews) { | |
let reviewExists = await isReviewPresent(review); | |
if (reviewExists) { | |
console.log(`Review for ${review.itemReviewed.name} already exists`); | |
} | |
else { | |
const response = await web5.dwn.records.create({ | |
data: review, | |
message: { | |
schema: schema.uri, | |
dataFormat: 'application/json', | |
published: true, | |
}, | |
}); | |
if (response.status.code === 202) { | |
console.log(`Review for ${review.itemReviewed.name} added successfully`); | |
} else { | |
console.log(`${response.status}. Error adding review for ${review.itemReviewed.name}`); | |
} | |
} | |
} | |
} | |
//Query book review (search for DWN records) | |
async function getReviews() { | |
let {records} = await web5.dwn.records.query({ | |
message: { | |
filter: { | |
schema: schema.uri | |
}, | |
}, | |
dateSort: 'createdAscending' | |
}); | |
return records; | |
} | |
//checks if review already exists (you may not want duplicate data in the DWN) | |
async function isReviewPresent(review) { | |
for(let record of existingReviews) { | |
let bookData = await record.data.json(); | |
let author = bookData.itemReviewed.author.name; | |
let title = bookData.itemReviewed.name; | |
if(author === review.itemReviewed.author.name | |
&& title === review.itemReviewed.name) { | |
return true; | |
} | |
}; | |
return false; | |
} | |
//Update book review rating | |
async function updateReviewRating(review, newRating) { | |
let bookData = await review.data.json(); | |
console.log(`old rating for ${bookData.itemReviewed.name}`, bookData.reviewRating.ratingValue); | |
let response = await review.update({ | |
data: { | |
"reviewRating": { | |
"ratingValue": newRating | |
} | |
} | |
}); | |
if (response.status.code === 202) { | |
const { record: updatedReview } = await web5.dwn.records.read({ | |
message: { | |
recordId: review.id, | |
}, | |
}); | |
const updatedData = await updatedReview.data.json(); | |
console.log(`updated rating for ${bookData.itemReviewed.name}`, updatedData.reviewRating.ratingValue); | |
} | |
else console.log(`${response.status}. Error updating rating for ${bookData.itemReviewed.name}`); | |
} | |
//Delete book review | |
async function deleteReviews() { | |
let records = await getReviews(); | |
for (const record of records) { | |
let title = (await record.data.json()).itemReviewed.name; | |
let response = await web5.dwn.records.delete({ | |
message: { | |
recordId: record.id, | |
} | |
}); | |
console.log(`deleted ${title}. status: ${response.status.code}`); | |
} | |
} | |
//Protocols define a data schema and permissions | |
async function installProtocol() { | |
const PROTOCOL_URI = 'https://book-review.xyz/'; | |
let protocolDefinition = { | |
"protocol": PROTOCOL_URI, | |
"types": { | |
"bookReview": { | |
"schema": PROTOCOL_URI + "schemas/bookReviewSchema", | |
"dataFormats": ["application/json"] | |
}, | |
"rating": { | |
"schema": PROTOCOL_URI + "schemas/ratingSchema", | |
"dataFormats": ["application/json"] | |
}, | |
"reviewBody": { | |
"schema": PROTOCOL_URI + "schemas/reviewBodySchema", | |
"dataFormats": ["application/json"] | |
}, | |
"reply": { | |
"schema": PROTOCOL_URI + "schemas/replySchema", | |
"dataFormats": ["application/json"] | |
} | |
}, | |
"structure": { | |
"bookReview": { | |
"$actions": [ | |
{ | |
"who": "anyone", | |
"can": "write" | |
}, | |
{ | |
"who": "anyone", | |
"can": "read" | |
} | |
], | |
"reply": { | |
"$actions": [ | |
{ | |
"who": "recipient", | |
"of": "bookReview", | |
"can": "write" | |
}, | |
{ | |
"who": "author", | |
"of": "bookReview", | |
"can": "read" | |
} | |
] | |
} | |
}, | |
"rating": { | |
"$actions": [ | |
{ | |
"who": "anyone", | |
"can": "read" | |
}, | |
{ | |
"who": "author", | |
"of": "bookReview", | |
"can": "write" | |
} | |
] | |
}, | |
"reviewBody": { | |
"$actions": [ | |
{ | |
"who": "author", | |
"of": "bookReview", | |
"can": "read" | |
}, | |
{ | |
"who": "recipient", | |
"of": "bookReview", | |
"can": "write" | |
} | |
] | |
} | |
} | |
}; | |
//Searches to see if protocol is already configured | |
const { protocols } = await web5.dwn.protocols.query({ | |
message: { | |
filter: { | |
protocol: PROTOCOL_URI, | |
}, | |
}, | |
}); | |
if(protocols.length == 0) { | |
//Installs protocol on user's DWN | |
const { protocol, status } = await web5.dwn.protocols.configure({ | |
message: { | |
definition: protocolDefinition | |
} | |
}); | |
if(status.code === 200) { | |
console.log(`Protocol ${protocol.definition.protocol} configured. Status: ${status.code}`); | |
} | |
else{ | |
console.log(`Error configuring protocol. Status: ${status.code}`); | |
} | |
} | |
else console.log(`Protocol ${PROTOCOL_URI} already configured`); | |
} | |
const existingReviews = await getReviews(); | |
await addReviews(); | |
await updateReviewRating(existingReviews[1], "4.2"); | |
await installProtocol(); | |
await deleteReviews(); | |
process.exit(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment