Skip to content

Commit

Permalink
[AppRouter] Initial Setup & Data-Fetching in Server Components (#781)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasio authored Jul 11, 2024
1 parent 6f288c3 commit 96ea386
Show file tree
Hide file tree
Showing 180 changed files with 7,793 additions and 8,355 deletions.
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"baseBranch": "trunk",
"updateInternalDependencies": "patch",
"privatePackages": { "version": true, "tag": false },
"ignore": ["@10up/wp-nextjs", "@10up/wp-multisite-nextjs", "@10up/wp-multisite-i18n-nextjs"]
"ignore": ["@10up/wp-nextjs", "@10up/wp-nextjs-app", "@10up/wp-multisite-nextjs", "@10up/wp-multisite-i18n-nextjs"]
}
6 changes: 6 additions & 0 deletions .changeset/forty-apes-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@headstartwp/core": minor
"@headstartwp/next": minor
---

Initial App Router Support
10,167 changes: 5,302 additions & 4,865 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"lint": "turbo run lint",
"wp-env": "npm run wp-env:start -w=wp/headless-wp",
"dev": "turbo run dev --parallel --filter=!./projects/wp-multisite-nextjs --filter=!./projects/wp-multisite-i18n-nextjs",
"dev:app": "turbo run dev --parallel --filter=!./projects/wp-multisite-nextjs --filter=!./projects/wp-multisite-i18n-nextjs --filter=!./projects/wp-nextjs",
"dev:multisite": "turbo run dev --parallel --filter=!./projects/wp-nextjs",
"prepare": "husky install",
"typedoc": "typedoc",
Expand All @@ -28,9 +29,7 @@
"publish": "npm run build:packages && npx changeset publish"
},
"workspaces": [
"packages/core",
"packages/next",
"packages/next-redis-cache-provider",
"packages/*",
"projects/*",
"wp/*"
],
Expand Down
13 changes: 12 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,19 @@
"types": "./dist/mjs/utils/index.d.ts"
},
"./react": {
"react-server": {
"import": "./dist/mjs/rsc/index.js",
"types": "./dist/mjs/rsc/index.d.ts"
},
"require": "./dist/cjs/react/index.js",
"import": "./dist/mjs/react/index.js",
"types": "./dist/mjs/react/index.d.ts"
},
"./rsc": {
"import": "./dist/mjs/rsc/index.js",
"require": "./dist/cjs/rsc/index.js",
"types": "./dist/mjs/rsc/index.d.ts"
},
"./test": "./test/server.ts"
},
"files": [
Expand Down Expand Up @@ -62,7 +71,9 @@
"ts-jest": "^29.0.3",
"typescript": "^5.4.5",
"whatwg-fetch": "^3.6.2",
"tsc-esm-fix": "^2.20.27"
"tsc-esm-fix": "^2.20.27",
"@types/react": "^18",
"@types/react-dom": "^18"
},
"dependencies": {
"@justinribeiro/lite-youtube": "^1.3.1",
Expand Down
1 change: 1 addition & 0 deletions packages/core/rsc.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './dist/mjs/rsc';
2 changes: 2 additions & 0 deletions packages/core/rsc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line import/extensions
module.exports = require('./dist/cjs/rsc');
4 changes: 0 additions & 4 deletions packages/core/src/data/api/fetch-utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { LOGTYPE, addQueryArgs, getHeadlessConfig, log } from '../../utils';

export const getAuthHeader = () => {
return null;
};

/**
* Fetch Wrapper to handle POST requests
*
Expand Down
28 changes: 28 additions & 0 deletions packages/core/src/data/fetchFn/__tests__/fetchAppSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { expectTypeOf } from 'expect-type';
import { AppEntity, EndpointParams } from '../..';
import { fetchAppSettings } from '../fetchAppSettings';

describe('fetchAppSettings', () => {
it('allows overriding types', async () => {
interface MyAppEntity extends AppEntity {
myCustomSetting: string;
}

interface Params extends EndpointParams {
includeCustomSettings: boolean;
}

const { data } = await fetchAppSettings<MyAppEntity, Params>({
params: {
includeCustomSettings: true,
},
});

expectTypeOf(data).toMatchTypeOf<
| {
myCustomSetting: string;
}
| undefined
>();
});
});
159 changes: 159 additions & 0 deletions packages/core/src/data/fetchFn/__tests__/fetchPost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { expectTypeOf } from 'expect-type';
import { PostParams } from '../..';
import { DRAFT_POST_ID, VALID_AUTH_TOKEN } from '../../../../test/server-handlers';
import { PostEntity } from '../../types';
import { fetchPost } from '../fetchPost';

describe('fetchPost', () => {
it('fetches data properly', async () => {
const { data } = await fetchPost({
params: { slug: 'modi-qui-dignissimos-sed-assumenda-sint-iusto' },
});

expect(data.post.slug).toBe('modi-qui-dignissimos-sed-assumenda-sint-iusto');
});

it('fetch by id', async () => {
const { data } = await fetchPost({ params: { id: 64 } });

expect(data.post.id).toBe(64);
expect(data.post.slug).toBe('ipsum-repudiandae-est-nam');
});

it('throws error if not found', async () => {
await expect(fetchPost({ params: { id: 123123123 } })).rejects.toThrow();
});

it('errors if fetches draft posts without authToken', async () => {
await expect(fetchPost({ params: { id: DRAFT_POST_ID } })).rejects.toThrow();
});

it('fetches draft posts with authToken', async () => {
const { data } = await fetchPost({
params: { id: DRAFT_POST_ID, authToken: VALID_AUTH_TOKEN },
});

expect(data?.post.id).toBe(57);
});

it('fetches draft posts with authToken and alternativePreviewAuthorizationHeader', async () => {
const { data } = await fetchPost({
params: { id: DRAFT_POST_ID, authToken: VALID_AUTH_TOKEN },
options: {
alternativePreviewAuthorizationHeader: true,
},
});

expect(data?.post.id).toBe(57);
});

it('errors if fetches revisions without authToken', async () => {
await expect(
fetchPost({ params: { id: DRAFT_POST_ID, revision: true } }),
).rejects.toThrow();
});

it('fetches revisions with authToken', async () => {
const { data } = await fetchPost({
params: { id: 64, revision: true, authToken: 'Fake Auth Token' },
});

expect(data.post.id).toBe(64);
expect(data.post.slug).toBe('ipsum-repudiandae-est-nam');
// ensure fields that don't exists in revisions are returned
expect(data.post.format).toBe('standard');
expect(data.post?.terms?.category[0]?.slug).toBe('news');
});

it('fetches revisions with authToken and alternativePreviewAuthorizationHeader', async () => {
const { data } = await fetchPost({
params: {
id: 64,
revision: true,
authToken: 'Fake Auth Token',
},
options: {
alternativePreviewAuthorizationHeader: true,
},
});

expect(data.post.id).toBe(64);
expect(data.post.slug).toBe('ipsum-repudiandae-est-nam');
// ensure fields that don't exists in revisions are returned
expect(data.post.format).toBe('standard');
expect(data.post?.terms?.category[0]?.slug).toBe('news');
});

it('reads param from the url and sets isMainQuery flag', async () => {
const result = await fetchPost({
path: '/modi-qui-dignissimos-sed-assumenda-sint-iusto/',
params: {
fullPath:
'https://js1.10up.com/2020/05/07/modi-qui-dignissimos-sed-assumenda-sint-iusto/',
},
});

expect(result.data.post.slug).toBe('modi-qui-dignissimos-sed-assumenda-sint-iusto');
expect(result.isMainQuery).toBe(true);

const result2 = await fetchPost({
params: { slug: 'modi-qui-dignissimos-sed-assumenda-sint-iusto' },
});

expect(result2.data.post.slug).toBe('modi-qui-dignissimos-sed-assumenda-sint-iusto');
expect(result2.isMainQuery).toBe(false);
});

it('matches post.link with current path when matchCurrentPath is set', async () => {
await expect(
fetchPost({
path: '/another-path',
params: {
slug: 'modi-qui-dignissimos-sed-assumenda-sint-iusto',
matchCurrentPath: true,
},
}),
).rejects.toThrow();

const { data } = await fetchPost({
path: '/another-path',
params: { slug: 'modi-qui-dignissimos-sed-assumenda-sint-iusto' },
});

expect(data.post.slug).toBe('modi-qui-dignissimos-sed-assumenda-sint-iusto');
});

it('matches post.link with fullPath when set', async () => {
const { data } = await fetchPost({
path: '/modi-qui-dignissimos-sed-assumenda-sint-iusto',
params: {
// force post path mapping against this path
fullPath:
'https://js1.10up.com/2020/05/07/modi-qui-dignissimos-sed-assumenda-sint-iusto',
},
});

expect(data.post.slug).toBe('modi-qui-dignissimos-sed-assumenda-sint-iusto');
});
});

describe('fetchPost types', () => {
it('allows overriding types', async () => {
interface Book extends PostEntity {
isbn: string;
}

interface BookParams extends PostParams {
isbn: string;
}

const { data } = await fetchPost<Book, BookParams>({ params: { isbn: 'sdasd' } });

expectTypeOf(data.post).toMatchTypeOf<
| {
isbn: string;
}
| undefined
>();
});
});
Loading

0 comments on commit 96ea386

Please sign in to comment.