first monorepo commit

This commit is contained in:
Jordi
2023-06-21 20:57:47 +02:00
parent 53fdf5522c
commit a330df2452
12 changed files with 571 additions and 266 deletions
+4
View File
@@ -0,0 +1,4 @@
{
"tabWidth": 2,
"useTabs": false
}
+416 -202
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -4,7 +4,8 @@
"build": "turbo run build",
"dev": "turbo run dev",
"lint": "turbo run lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\""
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"build:client": "turbo run dev --filter=@znd/client"
},
"devDependencies": {
"@turbo/gen": "^1.9.7",
+7 -9
View File
@@ -1,18 +1,16 @@
type Post = {
export type Post = {
slug: string;
title: string;
content: any;
};
type PostData = {
title: string;
slug: string;
export type PostWithContent = Post & {
content: string;
};
type CreateClientOpts = {
privateKey: string;
export type CreateClientOpts = {
blogId: string;
};
export declare function createClient({ privateKey }: CreateClientOpts): {
export declare function createClient({ blogId }: CreateClientOpts): {
getPosts(): Promise<Post[]>;
getPost(id: string): Promise<PostData>;
getPost(slug: string): Promise<PostWithContent>;
};
export {};
//# sourceMappingURL=index.d.ts.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAUA,KAAK,IAAI,GAAG;IACV,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,QAAQ,GAAG;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AACF,wBAAgB,YAAY,CAAC,EAAE,UAAU,EAAE,EAAE,gBAAgB;gBAKvC,QAAQ,IAAI,EAAE,CAAC;gBAOf,MAAM,GAAG,QAAQ,QAAQ,CAAC;EAI/C"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,GAAG,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,gBAAgB;gBAKnC,QAAQ,IAAI,EAAE,CAAC;kBAqBb,MAAM,GAAG,QAAQ,eAAe,CAAC;EAWxD"}
+32 -33
View File
@@ -1,44 +1,43 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createClient = void 0;
const BASE_URL = "https://localhost:300/api";
const BASE_URL = "http://localhost:3000/api";
function throwError(msg) {
throw new Error("[🍊] " + msg);
}
function wait(ms) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => setTimeout(resolve, ms));
});
}
function createClient({ privateKey }) {
if (!privateKey) {
throwError("privateKey is required");
export function createClient({ blogId }) {
if (!blogId) {
throwError("blogId is required");
}
return {
getPosts() {
return __awaiter(this, void 0, void 0, function* () {
return [
{ title: "How to start a cult", slug: "how-to-start-a-cult" },
{ title: "Cultpreneurship", slug: "cultpreneurship" },
{ title: "Groupthinking essentials", slug: "groupthinking-essentials" },
];
});
async getPosts() {
try {
const res = await fetch(`http://localhost:3000/api/public/${blogId}/posts`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
console.log('GETPOSTS 1', res);
if (!res.ok) {
console.log('GETPOSTS ERROR', res.status, res.statusText, res);
return [];
}
const data = await res.json();
console.log('GETPOSTS 3', data);
return data;
}
catch (error) {
console.error(error);
return [];
}
},
getPost(id) {
return __awaiter(this, void 0, void 0, function* () {
return { title: "hello world", slug: "hello-world", content: "..." };
async getPost(slug) {
const res = await fetch(`http://localhost:3000/api/public/${blogId}/post/${slug}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
return await res.json();
},
};
}
exports.createClient = createClient;
//# sourceMappingURL=index.js.map
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAE7C,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,IAAI,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,SAAe,IAAI,CAAC,EAAU;;QAC5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CAAA;AAgBD,SAAgB,YAAY,CAAC,EAAE,UAAU,EAAoB;IAC3D,IAAI,CAAC,UAAU,EAAE;QACf,UAAU,CAAC,wBAAwB,CAAC,CAAC;KACtC;IACD,OAAO;QACC,QAAQ;;gBACZ,OAAO;oBACL,EAAE,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,qBAAqB,EAAE;oBAC7D,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,iBAAiB,EAAE;oBACrD,EAAE,KAAK,EAAE,0BAA0B,EAAE,IAAI,EAAE,0BAA0B,EAAE;iBACxE,CAAC;YACJ,CAAC;SAAA;QACK,OAAO,CAAC,EAAU;;gBACtB,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YACvE,CAAC;SAAA;KACF,CAAC;AACJ,CAAC;AAhBD,oCAgBC"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAE7C,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,IAAI,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC;AACjC,CAAC;AAgBD,MAAM,UAAU,YAAY,CAAC,EAAE,MAAM,EAAoB;IACvD,IAAI,CAAC,MAAM,EAAE;QACX,UAAU,CAAC,oBAAoB,CAAC,CAAC;KAClC;IACD,OAAO;QACL,KAAK,CAAC,QAAQ;YACZ,IAAI;gBACF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oCAAoC,MAAM,QAAQ,EAAE;oBAC1E,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE;wBACP,cAAc,EAAE,kBAAkB;qBACnC;iBACF,CAAC,CAAA;gBACF,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,CAAA;gBAC9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;oBACX,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;oBAC9D,OAAO,EAAE,CAAC;iBACX;gBACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;gBAC7B,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;gBAC/B,OAAO,IAAI,CAAC;aACb;YAAC,OAAO,KAAK,EAAE;gBACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACrB,OAAO,EAAE,CAAC;aACX;QACH,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,IAAY;YACxB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oCAAoC,MAAM,SAAS,IAAI,EAAE,EAAE;gBACjF,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;aACF,CAAC,CAAA;YAEF,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC"}
+37 -17
View File
@@ -1,38 +1,58 @@
const BASE_URL = "https://localhost:300/api";
const BASE_URL = "http://localhost:3000/api";
function throwError(msg: string) {
throw new Error("[🍊] " + msg);
}
type Post = {
export type Post = {
slug: string;
title: string;
content: any;
};
type PostData = {
title: string;
slug: string;
export type PostWithContent = Post & {
content: string;
};
type CreateClientOpts = {
privateKey: string;
export type CreateClientOpts = {
blogId: string;
};
export function createClient({ privateKey }: CreateClientOpts) {
if (!privateKey) {
throwError("privateKey is required");
export function createClient({ blogId }: CreateClientOpts) {
if (!blogId) {
throwError("blogId is required");
}
return {
async getPosts(): Promise<Post[]> {
return [
{ title: "How to start a cult", slug: "how-to-start-a-cult" },
{ title: "Cultpreneurship", slug: "cultpreneurship" },
{ title: "Groupthinking essentials", slug: "groupthinking-essentials" },
];
try {
const res = await fetch(`http://localhost:3000/api/public/${blogId}/posts`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
})
console.log('GETPOSTS 1', res)
if (!res.ok) {
console.log('GETPOSTS ERROR', res.status, res.statusText, res)
return [];
}
const data = await res.json()
console.log('GETPOSTS 3', data)
return data;
} catch (error) {
console.error(error);
return [];
}
},
async getPost(id: string): Promise<PostData> {
return { title: "hello world", slug: "hello-world", content: "..." };
async getPost(slug: string): Promise<PostWithContent> {
const res = await fetch(`http://localhost:3000/api/public/${blogId}/post/${slug}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
})
return await res.json();
},
};
}
+2
View File
@@ -3,9 +3,11 @@
"version": "0.1.1-beta.1",
"description": "The typescript client for zendoblog",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"test": "npm test",
"build": "tsc",
"dev": "tsc -w",
"prepublishOnly": "npm run build",
"publish": "npm publish --access public",
"publish:beta": "npm publish --access public --tag beta"
+2 -2
View File
@@ -4,11 +4,11 @@
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"module": "CommonJS",
"module": "ES2020",
"outDir": "dist",
"rootDir": "./",
"sourceMap": true,
"target": "ES2015",
"target": "ES2020",
"strict": true,
"esModuleInterop": true,
"moduleResolution": "Node",
+6
View File
@@ -0,0 +1,6 @@
/** @type {import("prettier").Config} */
const config = {
plugins: [ require.resolve("prettier-plugin-tailwindcss") ],
};
module.exports = config;
+61
View File
@@ -0,0 +1,61 @@
# To Do
## Features
- [] Add PolyScale cache to Supabase for faster queries
- [] Categories
- [] Tags
- [] Featured Images
- [] Excerpts
- [] Authors
## Blogs
- [x] Create blog
- [x] Edit blog
- [x] Delete blog
- [x] View blog
- [x] View all blogs
- Make description optional
- Add emoji picker to Create Blog
- Redirect to blog after creating it
## Posts
- [] See "published at" and "updated at" dates in post list
- [x] View all posts
- [x] Create post
- [] View post
- [] Edit post
- [] Delete post
## SEO
- [] List what SEO metadata is needed for posts
- [] Add SEO metadata to blogs?
## API Client
- [x] Create API client
- [x] Add method to fetch all posts
- [x] Add method to fetch a single post
## Members
- [] Add members to a blog
- [] Remove members from a blog
- [] As a member, view all posts in a blog
- [] As a member, create a post in a blog
- [] As a member, edit a post in a blog
- [] As a member, delete a post in a blog
## React Components
- [] Create ZendoProvider component
- [] Create PostList component
- [] Create Post component
- [] Create ContentRenderer component
## User Feedback
- [] Custom Supabase URL for API client