Skip to content

Commit a0c3e02

Browse files
author
Frantz Kati
committed
feat(next): create basic package for using next.js framework
1 parent ef3c86c commit a0c3e02

File tree

26 files changed

+1694
-98
lines changed

26 files changed

+1694
-98
lines changed

examples/next/.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules/
2+
.env
3+
connect-session-knex.sqlite
4+
blog.sqlite
5+
storage/
6+
mikrotensei
7+
.next

examples/next/app.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
require('dotenv').config()
2+
const { auth } = require('@tensei/auth')
3+
const { next } = require('@tensei/next')
4+
const { tensei } = require('@tensei/core')
5+
const { graphql } = require('@tensei/graphql')
6+
7+
tensei()
8+
.plugins([auth().plugin(), next().plugin(), graphql().plugin()])
9+
.databaseConfig({
10+
dbName: 'mikrotensei.sqlite',
11+
type: 'sqlite'
12+
})
13+
.start()

examples/next/mikrotensei.sqlite

68 KB
Binary file not shown.

examples/next/nodemon.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"ignoreRoot": [".git"]
3+
}

examples/next/package.json

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "@examples/next",
3+
"version": "0.4.0",
4+
"main": "index.js",
5+
"license": "MIT",
6+
"dependencies": {
7+
"@mikro-orm/sqlite": "^4.3.2",
8+
"next": "^10.0.3",
9+
"react": "^17.0.1",
10+
"react-dom": "^17.0.1"
11+
},
12+
"devDependencies": {
13+
"nodemon": "^2.0.4",
14+
"prettier": "^2.0.5"
15+
},
16+
"scripts": {
17+
"start": "nodemon --watch ../../node_modules app.js",
18+
"prettier": "prettier --write './**/*.{js,json,css}'"
19+
},
20+
"private": true
21+
}

examples/next/pages/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Home() {
2+
return <h1>PAGE LOADED BY NEXT JS</h1>
3+
}

packages/core/Tensei.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,8 @@ export class Tensei implements TenseiContract {
237237

238238
this.server.listen(port, () => {
239239
this.ctx.logger.success(
240-
`🚀 Access your server on ${
241-
this.ctx.serverUrl || `http://127.0.0.1:${port}`
242-
}`
240+
`🚀 Access your server on ${this.ctx.serverUrl ||
241+
`http://127.0.0.1:${port}`}`
243242
)
244243
})
245244
}
@@ -563,7 +562,9 @@ export class Tensei implements TenseiContract {
563562
}
564563

565564
private mail(driverName: SupportedDrivers, mailConfig = {}) {
566-
this.ctx.mailer = mail().connection(driverName).config(mailConfig)
565+
this.ctx.mailer = mail()
566+
.connection(driverName)
567+
.config(mailConfig)
567568

568569
return this
569570
}

packages/core/database/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class Database {
128128
}
129129

130130
private generateEntityClass(resource: ResourceContract) {
131-
const entityClass = function () {}
131+
const entityClass = function() {}
132132

133133
Object.defineProperty(entityClass, 'name', {
134134
value: resource.data.pascalCaseName,

packages/express-session-mikro-orm/src/index.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ const StoreFactory = (Store: any) => {
4949
this.options.tableName,
5050
(table: any) => {
5151
table.string('session_id').primary()
52-
table.datetime('expires').nullable().index()
52+
table
53+
.datetime('expires')
54+
.nullable()
55+
.index()
5356
table.text('data').notNullable()
5457
}
5558
)

packages/media/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build
2+
tensei.sqlite
3+
.env

packages/media/src/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ class MediaLibrary {
5959

6060
if (fileFields.length) {
6161
MediaResource.fields([
62-
belongsTo(resource.data.name).nullable().hidden()
62+
belongsTo(resource.data.name)
63+
.nullable()
64+
.hidden()
6365
])
6466
}
6567
})

packages/media/src/resources.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,19 @@ export const mediaResource = () =>
1616
.searchable(),
1717
integer('Width').nullable(),
1818
integer('Height').nullable(),
19-
text('Original Filename').nullable().searchable(),
19+
text('Original Filename')
20+
.nullable()
21+
.searchable(),
2022
text('Extension')
2123
.description('The file extension, for example psd, pdf, png')
2224
.searchable(),
23-
text('Mime Type').nullable().searchable(),
25+
text('Mime Type')
26+
.nullable()
27+
.searchable(),
2428
text('Hash').searchable(),
25-
text('Path').nullable().searchable(),
29+
text('Path')
30+
.nullable()
31+
.searchable(),
2632
text('Alt Text').nullable(),
2733
text('Disk').nullable(),
2834
json('Disk Meta').nullable(),

packages/next/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build
2+
tensei.sqlite
3+
.env

packages/next/README.md

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<div align="center">
2+
<br />
3+
<br />
4+
<img src="https://res.cloudinary.com/bahdcoder/image/upload/v1604236130/Asset_1_4x_fhcfyg.png" width="450px">
5+
</div>
6+
7+
<br />
8+
9+
<br />
10+
11+
<div align="center">
12+
<h3>
13+
<strong>
14+
The fastest and easiest way to build powerful and secure APIs
15+
</strong>
16+
</h3>
17+
<p>Open source Node.js Headless CMS 🚀. </p>
18+
</div>
19+
20+
<br />
21+
22+
<div align="center">
23+
24+
25+
[![github-actions-image]][github-actions-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url]
26+
27+
</div>
28+
29+
<div align="center">
30+
<h3>
31+
<a href="https://tenseijs.com">
32+
Website
33+
</a>
34+
<span> | </span>
35+
<a href="https://tenseijs.com/docs">
36+
Guides
37+
</a>
38+
<span> | </span>
39+
<a href="CONTRIBUTING.md">
40+
Contributing
41+
</a>
42+
</h3>
43+
</div>
44+
45+
<div align="center">
46+
<sub>Built with ❤︎ by <a href="https://github.com/bahdcoder">Kati Frantz</a>
47+
</div>
48+
49+
[github-actions-image]: https://img.shields.io/github/workflow/status/tenseijs/tensei/Tests?style=for-the-badge
50+
[github-actions-url]: https://github.com/tenseijs/tensei/actions?query=workflow%3ATests "github-actions"
51+
52+
[npm-image]: https://img.shields.io/npm/v/@tensei/core.svg?style=for-the-badge&logo=npm
53+
[npm-url]: https://www.npmjs.com/package/@tensei/core "npm"
54+
55+
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
56+
57+
[license-url]: LICENSE.md
58+
[license-image]: https://img.shields.io/github/license/tenseijs/tensei?style=for-the-badge

packages/next/package.json

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "@tensei/next",
3+
"version": "0.4.1",
4+
"main": "./build/index.js",
5+
"license": "MIT",
6+
"types": "./build/index.d.ts",
7+
"files": [
8+
"build/"
9+
],
10+
"devDependencies": {},
11+
"scripts": {
12+
"prettier": "prettier --write './**/*.{js,json,ts,css}'",
13+
"build": "tsc --p tsconfig.json",
14+
"dev": "tsc --watch --p tsconfig.json",
15+
"test": "jest --verbose --runInBand --forceExit"
16+
},
17+
"dependencies": {
18+
"next": "^10.0.3"
19+
},
20+
"config": {
21+
"commitizen": {
22+
"path": "cz-conventional-changelog"
23+
}
24+
},
25+
"husky": {
26+
"hooks": {
27+
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
28+
}
29+
},
30+
"publishConfig": {
31+
"access": "public"
32+
}
33+
}

packages/next/src/index.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Next from 'next'
2+
import { plugin } from '@tensei/common'
3+
4+
class NextJSPlugin {
5+
plugin() {
6+
return plugin('Next JS').boot(async ctx => {
7+
const app = Next({
8+
dev: process.env.NODE_ENV !== 'production'
9+
})
10+
11+
await app.prepare()
12+
13+
ctx.app.all('*', (request, response) =>
14+
app.getRequestHandler()(request, response)
15+
)
16+
})
17+
}
18+
}
19+
20+
export const next = () => new NextJSPlugin()

packages/next/tsconfig.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2017",
4+
"module": "commonjs",
5+
"declaration": true,
6+
"outDir": "./build",
7+
"strict": true,
8+
"baseUrl": "./src",
9+
"esModuleInterop": true,
10+
"skipLibCheck": true,
11+
"forceConsistentCasingInFileNames": true,
12+
"types": ["@types/jest"]
13+
},
14+
"exclude": ["__tests__", "build"]
15+
}
+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { text, resource, textarea, belongsTo } from '@tensei/common'
22

33
export default resource('Comment').fields([
4-
text('Title').rules('required').searchable(),
4+
text('Title')
5+
.rules('required')
6+
.searchable(),
57
textarea('Body').rules('required'),
68
belongsTo('Post')
79
])

packages/tests/helpers/resources/Post.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ export default resource('Post')
7272
textarea('Content')
7373
.rules('required', 'max:2000', 'min:12')
7474
.hideOnIndex(),
75-
integer('Av. CPC').rules('required').hideOnDetail(),
75+
integer('Av. CPC')
76+
.rules('required')
77+
.hideOnDetail(),
7678
select('Category')
7779
.options([
7880
{

packages/tests/helpers/resources/Tag.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@ import { text, resource, textarea, belongsToMany, number } from '@tensei/common'
22

33
export default resource('Tag')
44
.fields([
5-
text('Name').rules('required').searchable(),
6-
number('Priority').nullable().default(1).rules('integer', 'under:5'),
5+
text('Name')
6+
.rules('required')
7+
.searchable(),
8+
number('Priority')
9+
.nullable()
10+
.default(1)
11+
.rules('integer', 'under:5'),
712
textarea('Description'),
813
belongsToMany('Post')
914
])

packages/tests/helpers/resources/User.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { text, resource, hasMany } from '@tensei/common'
22

33
export default resource('User')
44
.fields([
5-
text('Full name').searchable().rules('required'),
5+
text('Full name')
6+
.searchable()
7+
.rules('required'),
68
text('Email')
79
.unique()
810
.searchable()

packages/tests/helpers/resources/UserNoRel.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { text, hasMany, resource } from '@tensei/common'
22

33
export default resource('User')
44
.fields([
5-
text('Full name').searchable().rules('required'),
5+
text('Full name')
6+
.searchable()
7+
.rules('required'),
68
text('Email')
79
.unique()
810
.searchable()

packages/tests/packages/auth/auth.spec.ts

+22-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ test('Registers auth resources when plugin is registered', async () => {
1717
test('Can customize the name of the authenticator user', async () => {
1818
const {
1919
ctx: { resources }
20-
} = await setup([auth().user('Customer').plugin()])
20+
} = await setup([
21+
auth()
22+
.user('Customer')
23+
.plugin()
24+
])
2125

2226
expect(
2327
resources.find(resource => resource.data.name === 'Customer')
@@ -27,7 +31,11 @@ test('Can customize the name of the authenticator user', async () => {
2731
test('Enabling roles and permissions registers Role and permission resources', async () => {
2832
const {
2933
ctx: { resources }
30-
} = await setup([auth().rolesAndPermissions().plugin()])
34+
} = await setup([
35+
auth()
36+
.rolesAndPermissions()
37+
.plugin()
38+
])
3139

3240
expect(
3341
resources.filter(resource =>
@@ -205,7 +213,10 @@ test('Can request a password reset and reset password', async () => {
205213
},
206214
app
207215
} = await setup([
208-
auth().verifyEmails().user('Student').plugin(),
216+
auth()
217+
.verifyEmails()
218+
.user('Student')
219+
.plugin(),
209220
graphql().plugin(),
210221
setupFakeMailer(mailerMock)
211222
])
@@ -298,7 +309,10 @@ test('Can login and stay authenticated with cookie based applications', async ()
298309
},
299310
app
300311
} = await setup([
301-
auth().verifyEmails().user('Student').plugin(),
312+
auth()
313+
.verifyEmails()
314+
.user('Student')
315+
.plugin(),
302316
graphql().plugin()
303317
])
304318

@@ -621,7 +635,10 @@ test('if a refresh token is used twice (compromised), the user is automatically
621635
},
622636
app
623637
} = await setup([
624-
auth().user('Customer').noCookies().plugin(),
638+
auth()
639+
.user('Customer')
640+
.noCookies()
641+
.plugin(),
625642
graphql().plugin()
626643
])
627644

0 commit comments

Comments
 (0)