Skip to content

Commit

Permalink
Merge pull request #59 from WordPress/model
Browse files Browse the repository at this point in the history
Define model and refactor ApiClient
  • Loading branch information
psrpinto authored Sep 26, 2024
2 parents 8ad484c + 57f9011 commit cfb1636
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 144 deletions.
94 changes: 17 additions & 77 deletions src/api/ApiClient.ts
Original file line number Diff line number Diff line change
@@ -1,101 +1,41 @@
/* eslint-disable react/no-is-mounted */

import { PlaygroundClient } from '@wp-playground/client';
import { Post } from '@/api/Post';
import { Settings } from '@/api/Settings';
import { User } from '@/api/User';
import { PostContent, PostDate, PostTitle } from '@/parser/post';

export interface CreatePostBody {
guid: string;
}

export interface CreateUserBody {
username: string;
email: string;
password: string;
role?: string; // default roles: administrator, editor, author, subscriber (default)
firstname?: string;
lastname?: string;
}

export interface UpdatePostBody {
date?: PostDate;
title?: PostTitle;
content?: PostContent;
}
import { PostsApi } from '@/api/Posts';
import { SettingsApi } from '@/api/Settings';
import { UsersApi } from '@/api/Users';

export class ApiClient {
private readonly playgroundClient: PlaygroundClient;
private readonly _siteUrl: string;
private readonly _posts: PostsApi;
private readonly _settings: SettingsApi;
private readonly _users: UsersApi;

constructor( playgroundClient: PlaygroundClient, siteUrl: string ) {
this.playgroundClient = playgroundClient;
this._siteUrl = siteUrl;
this._posts = new PostsApi( this );
this._settings = new SettingsApi( this );
this._users = new UsersApi( this );
}

get siteUrl(): string {
return this._siteUrl;
}

async createPost( body: CreatePostBody ): Promise< Post > {
return ( await this.post( '/liberated_posts', {
meta: {
guid: body.guid,
},
} ) ) as Post;
}

async updatePost( id: number, body: UpdatePostBody ): Promise< Post > {
const actualBody: any = {};
if ( body.date ) {
actualBody.date = body.date.parsed;
}
if ( body.title ) {
actualBody.title = body.title.parsed;
}
if ( body.content ) {
actualBody.content = body.content.parsed;
actualBody.meta = {
raw_content: body.content.original,
};
}
return ( await this.post(
`/liberated_posts/${ id }`,
actualBody
) ) as Post;
get posts(): PostsApi {
return this._posts;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
async getPostByGuid( guid: string ): Promise< Post | null > {
return null;
get settings(): SettingsApi {
return this._settings;
}

async updateSiteTitle( title: string ): Promise< Settings > {
return ( await this.post( `/settings`, {
title,
} ) ) as Settings;
}

async createUser( body: CreateUserBody ): Promise< User > {
const actualBody: any = {
username: body.username,
email: body.email,
password: body.password,
};
if ( body.role ) {
actualBody.roles = [ body.role ];
}
if ( body.firstname ) {
actualBody.first_name = body.firstname;
}
if ( body.lastname ) {
actualBody.last_name = body.lastname;
}
return ( await this.post( `/users`, actualBody ) ) as User;
get users(): UsersApi {
return this._users;
}

private async get( route: string ): Promise< object > {
async get( route: string ): Promise< object > {
const response = await this.playgroundClient.request( {
url: `/index.php?rest_route=/wp/v2${ route }`,
method: 'GET',
Expand All @@ -107,7 +47,7 @@ export class ApiClient {
return response.json;
}

private async post( route: string, body: object ): Promise< object > {
async post( route: string, body: object ): Promise< object > {
const response = await this.playgroundClient.request( {
url: `/index.php?rest_route=/wp/v2${ route }`,
method: 'POST',
Expand Down
7 changes: 0 additions & 7 deletions src/api/Post.ts

This file was deleted.

86 changes: 86 additions & 0 deletions src/api/Posts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* eslint-disable camelcase */
import { WP_REST_API_Post } from 'wp-types';
type ApiPost = WP_REST_API_Post;
/* eslint-enable camelcase */

import { Post, PostContent, PostDate, PostTitle } from '@/model/Post';
import { ApiClient } from '@/api/ApiClient';

interface CreateBody {
guid: string;
}

interface UpdateBody {
date?: PostDate;
title?: PostTitle;
content?: PostContent;
}

interface PostMeta {
guid: string;
raw_title: string;
raw_date: string;
raw_content: string;
}

export class PostsApi {
// eslint-disable-next-line no-useless-constructor
constructor( private readonly client: ApiClient ) {}

async create( body: CreateBody ): Promise< Post > {
const response = ( await this.client.post( '/liberated_posts', {
meta: {
guid: body.guid,
},
} ) ) as ApiPost;
return makePostFromApiResponse( response );
}

async update( id: number, body: UpdateBody ): Promise< Post > {
const actualBody: any = {};
if ( body.date ) {
actualBody.date = body.date.parsed;
}
if ( body.title ) {
actualBody.title = body.title.parsed;
}
if ( body.content ) {
actualBody.content = body.content.parsed;
actualBody.meta = {
raw_content: body.content.original,
};
}
if ( Object.keys( actualBody ).length === 0 ) {
throw Error( 'attempting to update zero fields' );
}
const response = ( await this.client.post(
`/liberated_posts/${ id }`,
actualBody
) ) as ApiPost;
return makePostFromApiResponse( response );
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
async getByGuid( guid: string ): Promise< Post | null > {
return null;
}
}

function makePostFromApiResponse( response: ApiPost ): Post {
const meta = response.meta as unknown as PostMeta;
const date = new PostDate( response.date_gmt, meta.raw_date );
const title = new PostTitle( response.title.raw ?? '', meta.raw_title );
const content = new PostContent(
response.content.raw ?? '',
meta.raw_content
);

return {
guid: meta.guid,
id: response.id,
url: response.link,
date,
content,
title,
};
}
38 changes: 35 additions & 3 deletions src/api/Settings.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,39 @@
/* eslint-disable camelcase */

import { WP_REST_API_Settings } from 'wp-types';
type ApiSettings = WP_REST_API_Settings;
/* eslint-enable camelcase */

export interface Settings extends WP_REST_API_Settings {}
import { ApiClient } from '@/api/ApiClient';
import { SiteSettings } from '@/model/SiteSettings';

/* eslint-enable camelcase */
interface UpdateBody {
title?: string;
}

export class SettingsApi {
// eslint-disable-next-line no-useless-constructor
constructor( private readonly client: ApiClient ) {}

async update( body: UpdateBody ): Promise< SiteSettings > {
const actualBody: any = {};
if ( body.title ) {
actualBody.title = body.title;
}
if ( Object.keys( actualBody ).length === 0 ) {
throw Error( 'attempting to update zero fields' );
}
const response = ( await this.client.post(
`/settings`,
actualBody
) ) as ApiSettings;
return makeSiteSettingsFromApiResponse( response );
}
}

function makeSiteSettingsFromApiResponse(
response: ApiSettings
): SiteSettings {
return {
title: response.title,
};
}
7 changes: 0 additions & 7 deletions src/api/User.ts

This file was deleted.

53 changes: 53 additions & 0 deletions src/api/Users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-disable camelcase */
import { WP_REST_API_User } from 'wp-types';
type ApiUser = WP_REST_API_User;
/* eslint-enable camelcase */

import { ApiClient } from '@/api/ApiClient';
import { User } from '@/model/User';

interface CreateBody {
username: string;
email: string;
password: string;
role?: string; // default roles: administrator, editor, author, subscriber (default)
firstName?: string;
lastName?: string;
}

export class UsersApi {
// eslint-disable-next-line no-useless-constructor
constructor( private readonly client: ApiClient ) {}

async create( body: CreateBody ): Promise< User > {
const actualBody: any = {
username: body.username,
email: body.email,
password: body.password,
};
if ( body.role ) {
actualBody.roles = [ body.role ];
}
if ( body.firstName ) {
actualBody.first_name = body.firstName;
}
if ( body.lastName ) {
actualBody.last_name = body.lastName;
}
const response = ( await this.client.post(
`/users`,
actualBody
) ) as ApiUser;
return makeUserFromApiResponse( response );
}
}

function makeUserFromApiResponse( response: ApiUser ): User {
return {
username: response.username ?? '',
email: response.email ?? '',
role: response.roles ? response.roles[ 0 ] : '',
firstName: response.first_name ?? '',
lastName: response.last_name ?? '',
};
}
36 changes: 36 additions & 0 deletions src/model/Post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export interface Post {
id: number;
guid: string;
url: string;
date: PostDate;
title: PostTitle;
content: PostContent;
}

abstract class PostSection< T > {
original: string;
parsed: string;
constructor( original: string, parsed: string ) {
this.original = original;
this.parsed = parsed;
}
abstract value(): T;
}

export class PostDate extends PostSection< Date > {
value(): Date {
return new Date( this.parsed );
}
}

export class PostTitle extends PostSection< string > {
value(): string {
return this.parsed;
}
}

export class PostContent extends PostSection< string > {
value(): string {
return this.parsed;
}
}
3 changes: 3 additions & 0 deletions src/model/SiteSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface SiteSettings {
title: string;
}
7 changes: 7 additions & 0 deletions src/model/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface User {
username: string;
email: string;
role: string;
firstName: string;
lastName: string;
}
Loading

0 comments on commit cfb1636

Please sign in to comment.