mirror of
https://github.com/eliasrenman/gardentron.git
synced 2026-03-17 04:56:06 +01:00
chore: setup featherjs project
This commit is contained in:
54
server/src/app.ts
Normal file
54
server/src/app.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
// For more information about this file see https://dove.feathersjs.com/guides/cli/application.html
|
||||
import { feathers } from '@feathersjs/feathers'
|
||||
import configuration from '@feathersjs/configuration'
|
||||
import { koa, rest, bodyParser, errorHandler, parseAuthentication, cors, serveStatic } from '@feathersjs/koa'
|
||||
import socketio from '@feathersjs/socketio'
|
||||
|
||||
import { configurationValidator } from './configuration'
|
||||
import type { Application } from './declarations'
|
||||
import { logError } from './hooks/log-error'
|
||||
import { sqlite } from './sqlite'
|
||||
import { services } from './services/index'
|
||||
import { channels } from './channels'
|
||||
|
||||
const app: Application = koa(feathers())
|
||||
|
||||
// Load our app configuration (see config/ folder)
|
||||
app.configure(configuration(configurationValidator))
|
||||
|
||||
// Set up Koa middleware
|
||||
app.use(cors())
|
||||
app.use(serveStatic(app.get('public')))
|
||||
app.use(errorHandler())
|
||||
app.use(parseAuthentication())
|
||||
app.use(bodyParser())
|
||||
|
||||
// Configure services and transports
|
||||
app.configure(rest())
|
||||
app.configure(
|
||||
socketio({
|
||||
cors: {
|
||||
origin: app.get('origins')
|
||||
}
|
||||
})
|
||||
)
|
||||
app.configure(channels)
|
||||
app.configure(sqlite)
|
||||
app.configure(services)
|
||||
|
||||
// Register hooks that run on all service methods
|
||||
app.hooks({
|
||||
around: {
|
||||
all: [logError]
|
||||
},
|
||||
before: {},
|
||||
after: {},
|
||||
error: {}
|
||||
})
|
||||
// Register application setup and teardown hooks here
|
||||
app.hooks({
|
||||
setup: [],
|
||||
teardown: []
|
||||
})
|
||||
|
||||
export { app }
|
||||
38
server/src/channels.ts
Normal file
38
server/src/channels.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
// For more information about this file see https://dove.feathersjs.com/guides/cli/channels.html
|
||||
import type { RealTimeConnection, Params } from '@feathersjs/feathers'
|
||||
import type { AuthenticationResult } from '@feathersjs/authentication'
|
||||
import '@feathersjs/transport-commons'
|
||||
import type { Application, HookContext } from './declarations'
|
||||
import { logger } from './logger'
|
||||
|
||||
export const channels = (app: Application) => {
|
||||
logger.warn(
|
||||
'Publishing all events to all authenticated users. See `channels.ts` and https://dove.feathersjs.com/api/channels.html for more information.'
|
||||
)
|
||||
|
||||
app.on('connection', (connection: RealTimeConnection) => {
|
||||
// On a new real-time connection, add it to the anonymous channel
|
||||
app.channel('anonymous').join(connection)
|
||||
})
|
||||
|
||||
app.on('login', (authResult: AuthenticationResult, { connection }: Params) => {
|
||||
// connection can be undefined if there is no
|
||||
// real-time connection, e.g. when logging in via REST
|
||||
if (connection) {
|
||||
// The connection is no longer anonymous, remove it
|
||||
app.channel('anonymous').leave(connection)
|
||||
|
||||
// Add it to the authenticated user channel
|
||||
app.channel('authenticated').join(connection)
|
||||
}
|
||||
})
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
app.publish((data: any, context: HookContext) => {
|
||||
// Here you can add event publishers to channels set up in `channels.js`
|
||||
// To publish only for a specific event use `app.publish(eventname, () => {})`
|
||||
|
||||
// e.g. to publish all service events to all authenticated users use
|
||||
return app.channel('authenticated')
|
||||
})
|
||||
}
|
||||
34
server/src/client.ts
Normal file
34
server/src/client.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
// For more information about this file see https://dove.feathersjs.com/guides/cli/client.html
|
||||
import { feathers } from '@feathersjs/feathers'
|
||||
import type { TransportConnection, Application } from '@feathersjs/feathers'
|
||||
import authenticationClient from '@feathersjs/authentication-client'
|
||||
import type { AuthenticationClientOptions } from '@feathersjs/authentication-client'
|
||||
|
||||
export interface Configuration {
|
||||
connection: TransportConnection<ServiceTypes>
|
||||
}
|
||||
|
||||
export interface ServiceTypes {}
|
||||
|
||||
export type ClientApplication = Application<ServiceTypes, Configuration>
|
||||
|
||||
/**
|
||||
* Returns a typed client for the server app.
|
||||
*
|
||||
* @param connection The REST or Socket.io Feathers client connection
|
||||
* @param authenticationOptions Additional settings for the authentication client
|
||||
* @see https://dove.feathersjs.com/api/client.html
|
||||
* @returns The Feathers client application
|
||||
*/
|
||||
export const createClient = <Configuration = any>(
|
||||
connection: TransportConnection<ServiceTypes>,
|
||||
authenticationOptions: Partial<AuthenticationClientOptions> = {}
|
||||
) => {
|
||||
const client: ClientApplication = feathers()
|
||||
|
||||
client.configure(connection)
|
||||
client.configure(authenticationClient(authenticationOptions))
|
||||
client.set('connection', connection)
|
||||
|
||||
return client
|
||||
}
|
||||
17
server/src/configuration.ts
Normal file
17
server/src/configuration.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Type, getValidator, defaultAppConfiguration } from '@feathersjs/typebox'
|
||||
import type { Static } from '@feathersjs/typebox'
|
||||
|
||||
import { dataValidator } from './validators'
|
||||
|
||||
export const configurationSchema = Type.Intersect([
|
||||
defaultAppConfiguration,
|
||||
Type.Object({
|
||||
host: Type.String(),
|
||||
port: Type.Number(),
|
||||
public: Type.String()
|
||||
})
|
||||
])
|
||||
|
||||
export type ApplicationConfiguration = Static<typeof configurationSchema>
|
||||
|
||||
export const configurationValidator = getValidator(configurationSchema, dataValidator)
|
||||
20
server/src/declarations.ts
Normal file
20
server/src/declarations.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
// For more information about this file see https://dove.feathersjs.com/guides/cli/typescript.html
|
||||
import { HookContext as FeathersHookContext, NextFunction } from '@feathersjs/feathers'
|
||||
import { Application as FeathersApplication } from '@feathersjs/koa'
|
||||
import { ApplicationConfiguration } from './configuration'
|
||||
|
||||
export { NextFunction }
|
||||
|
||||
// The types for app.get(name) and app.set(name)
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface Configuration extends ApplicationConfiguration {}
|
||||
|
||||
// A mapping of service names to types. Will be extended in service files.
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
export interface ServiceTypes {}
|
||||
|
||||
// The application instance type that will be used everywhere else
|
||||
export type Application = FeathersApplication<ServiceTypes, Configuration>
|
||||
|
||||
// The context for hook functions - can be typed with a service class
|
||||
export type HookContext<S = any> = FeathersHookContext<Application, S>
|
||||
18
server/src/hooks/log-error.ts
Normal file
18
server/src/hooks/log-error.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
// For more information about this file see https://dove.feathersjs.com/guides/cli/log-error.html
|
||||
import type { HookContext, NextFunction } from '../declarations'
|
||||
import { logger } from '../logger'
|
||||
|
||||
export const logError = async (context: HookContext, next: NextFunction) => {
|
||||
try {
|
||||
await next()
|
||||
} catch (error: any) {
|
||||
logger.error(error.stack)
|
||||
|
||||
// Log validation errors
|
||||
if (error.data) {
|
||||
logger.error('Data: %O', error.data)
|
||||
}
|
||||
|
||||
throw error
|
||||
}
|
||||
}
|
||||
11
server/src/index.ts
Normal file
11
server/src/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { app } from './app'
|
||||
import { logger } from './logger'
|
||||
|
||||
const port = app.get('port')
|
||||
const host = app.get('host')
|
||||
|
||||
process.on('unhandledRejection', (reason) => logger.error('Unhandled Rejection %O', reason))
|
||||
|
||||
app.listen(port).then(() => {
|
||||
logger.info(`Feathers app listening on http://${host}:${port}`)
|
||||
})
|
||||
10
server/src/logger.ts
Normal file
10
server/src/logger.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
// For more information about this file see https://dove.feathersjs.com/guides/cli/logging.html
|
||||
import { createLogger, format, transports } from 'winston'
|
||||
|
||||
// Configure the Winston logger. For the complete documentation see https://github.com/winstonjs/winston
|
||||
export const logger = createLogger({
|
||||
// To see more detailed errors, change this to 'debug'
|
||||
level: 'info',
|
||||
format: format.combine(format.splat(), format.simple()),
|
||||
transports: [new transports.Console()]
|
||||
})
|
||||
6
server/src/services/index.ts
Normal file
6
server/src/services/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
// For more information about this file see https://dove.feathersjs.com/guides/cli/application.html#configure-functions
|
||||
import type { Application } from '../declarations'
|
||||
|
||||
export const services = (app: Application) => {
|
||||
// All services will be registered here
|
||||
}
|
||||
17
server/src/sqlite.ts
Normal file
17
server/src/sqlite.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// For more information about this file see https://dove.feathersjs.com/guides/cli/databases.html
|
||||
import knex from 'knex'
|
||||
import type { Knex } from 'knex'
|
||||
import type { Application } from './declarations'
|
||||
|
||||
declare module './declarations' {
|
||||
interface Configuration {
|
||||
sqliteClient: Knex
|
||||
}
|
||||
}
|
||||
|
||||
export const sqlite = (app: Application) => {
|
||||
const config = app.get('sqlite')
|
||||
const db = knex(config!)
|
||||
|
||||
app.set('sqliteClient', db)
|
||||
}
|
||||
29
server/src/validators.ts
Normal file
29
server/src/validators.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
// For more information about this file see https://dove.feathersjs.com/guides/cli/validators.html
|
||||
import { Ajv, addFormats } from '@feathersjs/schema'
|
||||
import type { FormatsPluginOptions } from '@feathersjs/schema'
|
||||
|
||||
const formats: FormatsPluginOptions = [
|
||||
'date-time',
|
||||
'time',
|
||||
'date',
|
||||
'email',
|
||||
'hostname',
|
||||
'ipv4',
|
||||
'ipv6',
|
||||
'uri',
|
||||
'uri-reference',
|
||||
'uuid',
|
||||
'uri-template',
|
||||
'json-pointer',
|
||||
'relative-json-pointer',
|
||||
'regex'
|
||||
]
|
||||
|
||||
export const dataValidator: Ajv = addFormats(new Ajv({}), formats)
|
||||
|
||||
export const queryValidator: Ajv = addFormats(
|
||||
new Ajv({
|
||||
coerceTypes: true
|
||||
}),
|
||||
formats
|
||||
)
|
||||
Reference in New Issue
Block a user