rajt 0.0.57 → 0.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +10 -7
  2. package/package.json +35 -15
  3. package/src/action-old.ts +72 -0
  4. package/src/action.ts +12 -61
  5. package/src/auth/ability.ts +2 -2
  6. package/src/auth/authnz.ts +3 -0
  7. package/src/auth/index.ts +0 -1
  8. package/src/auth/token.ts +27 -24
  9. package/src/bin/rajt.js +123 -0
  10. package/src/cli/commands/dev/index.ts +294 -0
  11. package/src/cli/commands/dev/utils.ts +215 -0
  12. package/src/cli/index.ts +69 -0
  13. package/src/cli/types.ts +1 -0
  14. package/src/create-app.ts +15 -9
  15. package/src/db/d1.d.ts +1 -0
  16. package/src/db/d1.ts +1 -0
  17. package/src/dev.ts +18 -15
  18. package/src/enum.ts +2 -75
  19. package/src/esbuild.mjs +11 -9
  20. package/src/http.ts +9 -8
  21. package/src/index.ts +1 -3
  22. package/src/prod-aws.ts +2 -17
  23. package/src/prod-cf.ts +1 -18
  24. package/src/prod.ts +16 -0
  25. package/src/request-old.ts +98 -0
  26. package/src/request.ts +152 -71
  27. package/src/response.ts +71 -26
  28. package/src/routes.ts +66 -2
  29. package/src/scripts/cache-routes.ts +1 -64
  30. package/src/types.ts +24 -4
  31. package/src/utils/environment.ts +3 -2
  32. package/src/utils/func.ts +2 -2
  33. package/src/utils/local-date.ts +13 -0
  34. package/src/utils/logger.ts +61 -0
  35. package/src/utils/port.ts +1 -3
  36. package/src/utils/resolve.ts +4 -3
  37. package/src/utils/shutdown.ts +19 -0
  38. package/src/validator.ts +68 -0
  39. package/src/auth/auth.ts +0 -33
  40. package/src/dynamodb/client.ts +0 -125
  41. package/src/dynamodb/compact.ts +0 -205
  42. package/src/dynamodb/decorators.ts +0 -126
  43. package/src/dynamodb/index.ts +0 -4
  44. package/src/dynamodb/model.ts +0 -258
  45. package/src/dynamodb/query-builder.ts +0 -174
  46. package/src/dynamodb/repository.ts +0 -31
  47. package/src/dynamodb/schema.ts +0 -107
  48. package/src/dynamodb/types.ts +0 -32
  49. package/src/utils/lenght.ts +0 -32
@@ -0,0 +1,294 @@
1
+ import { existsSync } from 'node:fs'
2
+ import { fileURLToPath } from 'node:url'
3
+ import { dirname, join, relative } from 'node:path'
4
+ import { spawn, type ChildProcess } from 'node:child_process'
5
+
6
+ import chokidar from 'chokidar'
7
+ import colors from 'picocolors'
8
+ import { defineCommand } from 'citty'
9
+ import type { ChokidarEventName } from '../../types'
10
+
11
+ import type { Miniflare } from 'miniflare'
12
+ import { build, createMiniflare } from './utils'
13
+ import { getAvailablePort } from '../../../utils/port'
14
+ import shutdown from '../../../utils/shutdown'
15
+
16
+ const __dirname = join(dirname(fileURLToPath(import.meta.url)), '../../../../../../')
17
+
18
+ export default defineCommand({
19
+ meta: {
20
+ name: 'dev',
21
+ description: '💻 Start the localhost server\n',
22
+ },
23
+ args: {
24
+ port: {
25
+ description: 'Port to listen on',
26
+ type: 'number',
27
+ default: 3000,
28
+ },
29
+ host: {
30
+ description: 'Host to forward requests to, defaults to the zone of project',
31
+ type: 'string',
32
+ default: 'localhost',
33
+ },
34
+ platform: {
35
+ alias: 'p',
36
+ description: 'Environment platform',
37
+ type: 'enum',
38
+ options: ['aws', 'cf', 'node'] as const,
39
+ required: true,
40
+ },
41
+ },
42
+ async run({ args }) {
43
+ const platform = args.p || args.platform
44
+ const desiredPort = args.port ? Number(args.port) : 3000
45
+ const host = args.host ? String(args.host) : 'localhost'
46
+ switch (platform) {
47
+ case 'aws':
48
+ return withPort(desiredPort, async (port) => {
49
+ let isBuilding = false
50
+ let lambda: ChildProcess | null = null
51
+
52
+ const buildLambda = async () => {
53
+ if (isBuilding) return
54
+ isBuilding = true
55
+ logger.step('Building lambda')
56
+ try {
57
+ await build(platform)
58
+ if (!lambda) await startLambda()
59
+ } catch (e) {
60
+ logger.error('Build failed:', e)
61
+ process.exit(0)
62
+ } finally {
63
+ isBuilding = false
64
+ }
65
+ }
66
+
67
+ const stopLambda = async () => {
68
+ if (!lambda) return
69
+ logger.step('Stopping lambda process...')
70
+ try {
71
+ if (!lambda?.killed) {
72
+ lambda.kill('SIGTERM')
73
+ await wait(1000)
74
+
75
+ if (!lambda?.killed) { // force kill
76
+ lambda.kill('SIGKILL')
77
+ await wait(1000)
78
+ }
79
+ }
80
+
81
+ lambda = null
82
+ } catch (e) {
83
+ logger.warn('Error stopping lambda:', e)
84
+ }
85
+ }
86
+
87
+ const startLambda = async () => {
88
+ await stopLambda()
89
+
90
+ lambda = spawn(
91
+ 'sam',
92
+ [
93
+ 'local', 'start-api',
94
+ '--warm-containers', 'LAZY',
95
+ '--debug', '--template-file', join(__dirname, 'template-dev.yaml'),
96
+ '--port', args.port,
97
+ ],
98
+ {
99
+ stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
100
+ // stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
101
+ shell: process.platform == 'win32',
102
+ env: {...process.env, DOCKER_HOST: getDockerHost()},
103
+ }
104
+ ).on('exit', code => {
105
+ logger.step(`Lambda process exited with code ${code ?? 0}`)
106
+ if (code != 0 && code != null)
107
+ logger.error('Lambda process crashed, waiting for restart...')
108
+
109
+ lambda = null
110
+ })
111
+ .on('message', msg => {
112
+ if (process.send) process.send(msg)
113
+ }).on('disconnect', () => {
114
+ if (process.disconnect) process.disconnect()
115
+ }).on('error', e => {
116
+ logger.error('Lambda process error:', e)
117
+ lambda = null
118
+ })
119
+
120
+ await wait(2000)
121
+
122
+ logger.step('Lambda process started successfully')
123
+ }
124
+
125
+ await buildLambda()
126
+ logger.step(`API running on http://${host}:${port}`)
127
+
128
+ watch(async () => {
129
+ await buildLambda()
130
+ })
131
+
132
+ shutdown(async () => {
133
+ await stopLambda()
134
+ })
135
+ })
136
+ case 'cf':
137
+ return withPort(desiredPort, async (port) => {
138
+ let isBuilding = false
139
+
140
+ const buildWorker = async () => {
141
+ if (isBuilding) return
142
+ isBuilding = true
143
+ logger.step('Building worker')
144
+ try {
145
+ await build(platform)
146
+ await startWorker()
147
+ } catch (e) {
148
+ logger.error('Build failed:', e)
149
+ process.exit(0)
150
+ } finally {
151
+ isBuilding = false
152
+ }
153
+ }
154
+
155
+ let worker: Miniflare | null = null
156
+ const startWorker = async () => {
157
+ if (worker) await worker.dispose()
158
+
159
+ worker = await createMiniflare({ port, host, liveReload: false })
160
+ }
161
+
162
+ await buildWorker()
163
+ logger.step(`API running on http://${host}:${port}`)
164
+
165
+ watch(async () => {
166
+ logger.step('Restarting server')
167
+ await buildWorker()
168
+ logger.step('Server restarted')
169
+ })
170
+ })
171
+ case 'node':
172
+ return withPort(desiredPort, async (port) => {
173
+ logger.step(`API running on http://${host}:${port}`)
174
+
175
+ spawn(
176
+ process.execPath,
177
+ [
178
+ join(__dirname, 'node_modules/.bin/tsx'), 'watch', join(__dirname, 'node_modules/rajt/src/dev.ts'),
179
+ ],
180
+ {
181
+ stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
182
+ env: {...process.env, PORT: args.port},
183
+ }
184
+ ).on('exit', code => process.exit(code ?? 0))
185
+ .on('message', msg => {
186
+ if (process.send) process.send(msg)
187
+ }).on('disconnect', () => {
188
+ if (process.disconnect) process.disconnect()
189
+ })
190
+ })
191
+ default:
192
+ return logger.warn(
193
+ `🟠 Provide a valid platform: ${['aws', 'cf', 'node'].map(p => colors.blue(p)).join(', ')}.\n`
194
+ )
195
+ }
196
+ },
197
+ })
198
+
199
+ function withPort(desiredPort: number, cb: (port: number) => void) {
200
+ getAvailablePort(desiredPort)
201
+ .then((port: number) => {
202
+ if (port != desiredPort)
203
+ logger.warn(`Port ${desiredPort} was in use, using ${port} as a fallback`)
204
+
205
+ cb(port)
206
+ }).catch(e => logger.error('Error finding available port:', e))
207
+ }
208
+
209
+ function getAssetChangeMessage(
210
+ e: ChokidarEventName,
211
+ path: string
212
+ ): string {
213
+ path = relative(__dirname, path)
214
+ switch (e) {
215
+ case 'add':
216
+ return `File ${path} was added`
217
+ case 'addDir':
218
+ return `Directory ${path} was added`
219
+ case 'unlink':
220
+ return `File ${path} was removed`
221
+ case 'unlinkDir':
222
+ return `Directory ${path} was removed`
223
+ case 'change':
224
+ default:
225
+ return `${path} changed`
226
+ }
227
+ }
228
+
229
+ async function watch(cb: (e: ChokidarEventName | string, file: string) => Promise<void>) {
230
+ const codeWatcher = chokidar.watch([
231
+ join(__dirname, 'actions/**/*.ts'),
232
+ join(__dirname, 'configs/**/*.ts'),
233
+ join(__dirname, 'enums/**/*.ts'),
234
+ join(__dirname, 'locales/**/*.ts'),
235
+ join(__dirname, 'middlewares/**/*.ts'),
236
+ join(__dirname, 'models/**/*.ts'),
237
+ join(__dirname, 'utils/**/*.ts'),
238
+ join(__dirname, '.env.dev'),
239
+ join(__dirname, '.env.prod'),
240
+ join(__dirname, 'package.json'),
241
+ join(__dirname, 'wrangler.toml'),
242
+ ], {
243
+ ignored: /(^|[/\\])\../, // ignore hidden files
244
+ persistent: true,
245
+ ignoreInitial: true,
246
+ awaitWriteFinish: {
247
+ stabilityThreshold: 200,
248
+ pollInterval: 100,
249
+ },
250
+ })
251
+ let restartTimeout: NodeJS.Timeout | null = null
252
+
253
+ const watcher = (e: ChokidarEventName) => async (file: string) => {
254
+ logger.step(getAssetChangeMessage(e, file))
255
+
256
+ if (restartTimeout)
257
+ clearTimeout(restartTimeout)
258
+
259
+ restartTimeout = setTimeout(async () => {
260
+ await cb(e, file)
261
+ }, 300)
262
+ }
263
+
264
+ codeWatcher.on('change', watcher('change'))
265
+ codeWatcher.on('add', watcher('add'))
266
+ codeWatcher.on('unlink', watcher('unlink'))
267
+ codeWatcher.on('addDir', watcher('addDir'))
268
+ codeWatcher.on('unlinkDir', watcher('unlinkDir'))
269
+
270
+ logger.step('Watching for file changes')
271
+ }
272
+
273
+ async function wait(ms: number) {
274
+ return new Promise(r => setTimeout(r, ms))
275
+ }
276
+
277
+ function getDockerHost() {
278
+ const platform = process.platform
279
+
280
+ if (platform == 'darwin') {
281
+ for (const socket of [
282
+ '/Users/'+ process.env.USER +'/.docker/run/docker.sock',
283
+ '/var/run/docker.sock',
284
+ process.env.DOCKER_HOST
285
+ ]) {
286
+ if (socket && existsSync(socket.replace(/^unix:\/\//, '')))
287
+ return socket.includes('://') ? socket : `unix://${socket}`
288
+ }
289
+
290
+ return 'tcp://localhost:2375'
291
+ }
292
+
293
+ return process.env.DOCKER_HOST || (platform == 'win32' ? 'tcp://localhost:2375' : 'unix:///var/run/docker.sock')
294
+ }
@@ -0,0 +1,215 @@
1
+ import esbuild from 'esbuild'
2
+ import TOML from '@iarna/toml'
3
+ import { Miniflare } from 'miniflare'
4
+ import { fileURLToPath } from 'node:url'
5
+ import { mkdirSync, existsSync, readdirSync, rmSync, copyFileSync } from 'node:fs'
6
+ import { readFile, stat, writeFile } from 'node:fs/promises'
7
+ import { basename, dirname, join, relative } from 'node:path'
8
+
9
+ import { cacheRoutes } from '../../../routes'
10
+
11
+ const __dirname = join(dirname(fileURLToPath(import.meta.url)), '../../../../../../')
12
+ const __rajt = join(__dirname, 'node_modules/rajt/src')
13
+
14
+ export const formatSize = (bytes: number) => {
15
+ if (bytes < 1024) return `${bytes}b`
16
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)}kb`
17
+ return `${(bytes / (1024 * 1024)).toFixed(2)}mb`
18
+ }
19
+
20
+ export const formatTime = (ms: number) => {
21
+ if (ms < 1000) return `${ms}ms`
22
+ return `${(ms / 1000).toFixed(2)}s`
23
+ }
24
+
25
+ export const build = async (platform: 'aws' | 'cf' | 'node') => {
26
+ const startTime = Date.now()
27
+
28
+ const isCF = platform == 'cf'
29
+ const distDir = join(__dirname, 'dist')
30
+
31
+ existsSync(distDir)
32
+ ? readdirSync(distDir).forEach(file => rmSync(join(distDir, file), { recursive: true, force: true }))
33
+ : mkdirSync(distDir, { recursive: true })
34
+
35
+ if (isCF) {
36
+ for (let file of [
37
+ 'wrangler.toml',
38
+ ]) {
39
+ file = join(__dirname, file)
40
+ if (existsSync(file))
41
+ copyFileSync(file, join(__dirname, 'dist', basename(file)))
42
+ }
43
+ }
44
+
45
+ const opts = {
46
+ entryPoints: [join(__rajt, `prod-${platform}.ts`)],
47
+ bundle: true,
48
+ minify: false,
49
+ outfile: join(__dirname, 'dist/index.js'),
50
+ format: 'esm',
51
+ target: isCF ? 'es2022' : 'node20',
52
+ // platform: 'neutral',
53
+ platform: isCF ? 'browser' : 'node',
54
+ conditions: isCF ? ['worker', 'browser'] : [],
55
+ treeShaking: true,
56
+ legalComments: 'none',
57
+ external: [
58
+ '@aws-sdk', '@smithy',
59
+ ...(isCF ? [
60
+ 'cloudflare:workers',
61
+ 'node:crypto', 'crypto',
62
+ 'node:buffer', 'buffer',
63
+ ] : []),
64
+ ],
65
+ metafile: true,
66
+ write: false,
67
+ // define: {
68
+ // 'process.env.NODE_ENV': '"development"'
69
+ // },
70
+ // loader: {
71
+ // '.ts': 'ts',
72
+ // '.js': 'js'
73
+ // },
74
+ // tsconfig: join(__dirname, 'tsconfig.json'),
75
+ // sourcemap: true,
76
+ // logLevel: 'info',
77
+ plugins: [
78
+ {
79
+ name: 'preserve-class-names',
80
+ setup(build) {
81
+ build.onLoad(
82
+ { filter: /(actions|features)\/.*\.ts$/ },
83
+ async (args) => {
84
+ const contents = await readFile(args.path, 'utf8')
85
+ const result = await esbuild.transform(contents, {
86
+ loader: 'ts',
87
+ minify: true,
88
+ keepNames: true
89
+ })
90
+ return { contents: result.code, loader: 'ts' }
91
+ }
92
+ )
93
+ },
94
+ },
95
+ {
96
+ name: 'remove-use-strict',
97
+ setup(build) {
98
+ build.onEnd(async (result) => {
99
+ if (!result.outputFiles) return
100
+
101
+ const files = result.outputFiles.filter(file => file.path.endsWith('.js'))
102
+ await Promise.all(files.map(async file => {
103
+ if (!file.path.endsWith('.js')) return
104
+
105
+ await writeFile(
106
+ file.path,
107
+ new TextDecoder()
108
+ .decode(file.contents)
109
+ .replace(/(["'`])\s*use strict\s*\1;?|`use strict`;?/g, '')
110
+ )
111
+ }))
112
+ })
113
+ }
114
+ },
115
+ ],
116
+ }
117
+
118
+ await cacheRoutes()
119
+
120
+ logger.step('Routes cached')
121
+
122
+ const result = await esbuild.build(opts)
123
+ if (!result?.metafile) throw Error('build fail')
124
+
125
+ logger.step('Build completed successfully')
126
+
127
+ const stats = await stat(opts.outfile)
128
+ const size = formatSize(stats.size)
129
+
130
+ logger.step(
131
+ `Build done in ${formatTime(Date.now() - startTime)}`,
132
+ `${relative(join(__dirname, 'node_modules/rajt/src'), opts.entryPoints[0])} → ${relative(__dirname, opts.outfile)}`,
133
+ `Size: ${size}`,
134
+ `Files: ${Object.keys(result.metafile.outputs).length}`
135
+ )
136
+ }
137
+
138
+ async function parseWranglerConfig(file: string) {
139
+ try {
140
+ return TOML.parse(await readFile(join(__dirname, file), 'utf-8'))
141
+ } catch (e) {
142
+ logger.warn(`Could not parse ${file}, using defaults`)
143
+ return {}
144
+ }
145
+ }
146
+
147
+ export async function createMiniflare(options = {}, configPath = 'wrangler.toml') {
148
+ const config = await parseWranglerConfig(configPath)
149
+
150
+ return new Miniflare({
151
+ host: options.host || 'localhost',
152
+ port: options.port || 8787,
153
+ https: options.https || false,
154
+ httpsKey: options.httpsKey,
155
+ httpsCert: options.httpsCert,
156
+ liveReload: options.liveReload !== false,
157
+ updateCheck: false,
158
+
159
+ scriptPath: join(__dirname, 'dist/index.js'),
160
+ compatibilityDate: config.compatibility_date || '2024-11-01',
161
+ compatibilityFlags: config.compatibility_flags || [
162
+ 'nodejs_compat',
163
+ ],
164
+
165
+ bindings: {
166
+ // MY_VARIABLE: 'value',
167
+ // ENVIRONMENT: 'development',
168
+ ...config.vars,
169
+ },
170
+
171
+ d1Databases: Object.fromEntries(config.d1_databases.map(db => [db.binding, db.database_id])),
172
+
173
+ modules: [
174
+ { type: "ESModule", path: "dist/index.js" },
175
+ ],
176
+ // modules: true,
177
+ // modulesRules: [
178
+ // { type: 'ESModule', include: ['**/*.js', '**/*.ts'] },
179
+ // ],
180
+
181
+ kvPersist: join(__dirname, '.wrangler/state/v3/kv'),
182
+ cachePersist: join(__dirname, '.wrangler/state/v3/cache'),
183
+ d1Persist: join(__dirname, '.wrangler/state/v3/d1'),
184
+ r2Persist: join(__dirname, '.wrangler/state/v3/r2'),
185
+ durablesPersist: join(__dirname, '.wrangler/state/v3/durable_objects'),
186
+
187
+ verbose: false,
188
+
189
+ // Logging
190
+ // log: new console.Console({
191
+ // stdout: process.stdout,
192
+ // stderr: process.stderr,
193
+ // inspectOptions: { depth: 3 }
194
+ // }),
195
+
196
+ cfFetch: false, // disable cf requests
197
+ upstream: config.upstream || 'https://example.com',
198
+
199
+ sitePath: config.site?.bucket ?
200
+ join(__dirname, config.site.bucket) : undefined,
201
+ siteInclude: config.site?.include || ['**/*'],
202
+ siteExclude: config.site?.exclude || [],
203
+
204
+ globalAsyncIO: true,
205
+ globalTimers: true,
206
+ globalRandom: true,
207
+
208
+ inspectorPort: options.inspectorPort || 9229,
209
+
210
+ cache: true,
211
+ cacheWarnUsage: true,
212
+
213
+ ...options
214
+ })
215
+ }
@@ -0,0 +1,69 @@
1
+ import { defineCommand, runMain, renderUsage } from 'citty'
2
+ import type { ArgsDef, CommandDef } from 'citty'
3
+ import colors from 'picocolors'
4
+ import { createConsola } from 'consola'
5
+
6
+ import { version as rajtVersion } from '../../package.json'
7
+
8
+ import logger, { type ILogger } from '../utils/logger'
9
+
10
+ import dev from './commands/dev'
11
+
12
+ // Prevent non-internal logs
13
+ (globalThis as any).logger = logger // Make it global in Node.js and browser
14
+ declare global { var logger: ILogger }
15
+
16
+ // console.log = () => {}
17
+ console.info = () => {}
18
+ console.warn = () => {}
19
+ console.error = () => {}
20
+
21
+ /**
22
+ * The main entrypoint for the CLI.
23
+ * main only gets called when the script is run directly, not when it's imported as a module.
24
+ */
25
+ const directly = () => {
26
+ try {
27
+ // @ts-ignore
28
+ return typeof vitest == 'undefined'
29
+ && (
30
+ ![typeof require, typeof module].includes('undefined') && require.main == module
31
+ || import.meta.url == `file://${process.argv[1]}`
32
+ )
33
+ } catch {
34
+ return false
35
+ }
36
+ }
37
+
38
+ const name = 'Rajt CLI'
39
+ const version = [name, colors.isColorSupported ? colors.gray('v'+rajtVersion) : rajtVersion].join(' ')
40
+
41
+ if (directly()) {
42
+ const _args = process.argv.slice(2)
43
+ if (_args.length == 1 && ['-v', '--version', '--v', '-version'].includes(_args[0])) {
44
+ console.log(version)
45
+ process.exit(0)
46
+ }
47
+
48
+ const consola = createConsola({ formatOptions: {date: false} })
49
+ async function showUsage<T extends ArgsDef = ArgsDef>(cmd: CommandDef<T>, parent?: CommandDef<T>) {
50
+ try {
51
+ consola.log((await renderUsage(cmd, parent)).split('\n').slice(1).join('\n') + '\n')
52
+ } catch (error) {
53
+ consola.error(error)
54
+ }
55
+ }
56
+
57
+ const main = defineCommand({
58
+ meta: {
59
+ name: 'rajt',
60
+ version: rajtVersion,
61
+ description: name,
62
+ },
63
+ subCommands: {
64
+ dev,
65
+ },
66
+ })
67
+
68
+ runMain(main, { rawArgs: _args?.length ? undefined : ['-h'], showUsage })
69
+ }
@@ -0,0 +1 @@
1
+ export type ChokidarEventName = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir'
package/src/create-app.ts CHANGED
@@ -1,18 +1,21 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import { Hono } from 'hono'
3
+ import { logger } from 'hono/logger'
3
4
  import type { Env, Context, ErrorHandler, NotFoundHandler, Next } from 'hono'
4
5
  // import type { MiddlewareHandler } from 'hono'
5
6
  // import { createMiddleware } from 'hono/factory'
6
7
  // import type { H, Handler, HandlerResponse } from 'hono/types'
7
8
  import type { HTTPResponseError } from 'hono/types'
9
+ import colors from 'picocolors'
10
+ import { Envir } from 't0n'
8
11
  import type { Routes } from './types'
9
12
  import { BadRequest, Unauthorized } from './exceptions'
10
13
  import { resolve, resolveMiddleware } from './utils/resolve'
11
14
  import { getMiddlewares, getHandler } from './register'
12
15
  import { isDev } from './utils/environment'
13
- import { Auth } from './auth'
16
+ import localDate from './utils/local-date'
17
+ import request from './request'
14
18
  import response from './response'
15
- import cx from './context'
16
19
 
17
20
  type InitFunction<E extends Env = Env> = (app: Hono<E>) => void
18
21
 
@@ -31,13 +34,13 @@ const EHandler = async (e: Error | HTTPResponseError) => {
31
34
 
32
35
  switch (true) {
33
36
  case e instanceof Unauthorized:
34
- case 'status' in e && e.status === 401:
37
+ case 'status' in e && e.status == 401:
35
38
  return response.unauthorized()
36
39
 
37
40
  case e instanceof BadRequest:
38
- case 'status' in e && e.status === 400:
41
+ case 'status' in e && e.status == 400:
39
42
  // @ts-ignore
40
- return response.badRequest(undefined, e?.message)
43
+ return response.badRequest(null, e?.message)
41
44
 
42
45
  default:
43
46
  return response.internalError(
@@ -78,13 +81,16 @@ export const createApp = <E extends Env>(options?: ServerOptions<E>) => {
78
81
  // const root = options?.root ?? '/'
79
82
  const app = options?.app ?? new Hono<E>()
80
83
 
84
+ if (isDev())
85
+ app.use('*', logger((...args: any[]) => console.log(colors.gray(localDate()), ...args)))
86
+
81
87
  app.use(async (c: Context, next: Next) => {
82
- cx.setContext(c)
83
- Auth.resolve()
88
+ c.set('_', new request(c))
89
+ if (c.env) Envir.add(c.env)
84
90
  await next()
85
91
  })
86
92
  getMiddlewares().forEach(mw => {
87
- const h = async (c: Context, next: Next) => await resolveMiddleware(mw)(cx.cx, next)
93
+ const h = async (c: Context, next: Next) => await resolveMiddleware(mw)(c.get('_'), next)
88
94
  // @ts-ignore
89
95
  mw?.path ? app.use(String(mw.path), h) : app.use(h)
90
96
  })
@@ -111,7 +117,7 @@ export const createApp = <E extends Env>(options?: ServerOptions<E>) => {
111
117
 
112
118
  function mw(...objs: string[]): Function[] {
113
119
  return objs.flatMap(obj => {
114
- if (typeof obj !== 'string') return null
120
+ if (typeof obj != 'string') return null
115
121
  // @ts-ignore
116
122
  return getHandler(obj)?.mw || null
117
123
  }).flat().filter(Boolean)
package/src/db/d1.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from 'forj/d1/types'
package/src/db/d1.ts ADDED
@@ -0,0 +1 @@
1
+ export * from 'forj/d1'