@hugomrdias/foxer 0.0.1
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.
- package/README.md +56 -0
- package/dist/src/api/index.d.ts +2 -0
- package/dist/src/api/index.d.ts.map +1 -0
- package/dist/src/api/index.js +2 -0
- package/dist/src/api/index.js.map +1 -0
- package/dist/src/api/runner.d.ts +12 -0
- package/dist/src/api/runner.d.ts.map +1 -0
- package/dist/src/api/runner.js +29 -0
- package/dist/src/api/runner.js.map +1 -0
- package/dist/src/api/server.d.ts +18 -0
- package/dist/src/api/server.d.ts.map +1 -0
- package/dist/src/api/server.js +21 -0
- package/dist/src/api/server.js.map +1 -0
- package/dist/src/api/sql-middleware.d.ts +7 -0
- package/dist/src/api/sql-middleware.d.ts.map +1 -0
- package/dist/src/api/sql-middleware.js +95 -0
- package/dist/src/api/sql-middleware.js.map +1 -0
- package/dist/src/api/sql.d.ts +14 -0
- package/dist/src/api/sql.d.ts.map +1 -0
- package/dist/src/api/sql.js +108 -0
- package/dist/src/api/sql.js.map +1 -0
- package/dist/src/api/sse.d.ts +3 -0
- package/dist/src/api/sse.d.ts.map +1 -0
- package/dist/src/api/sse.js +11 -0
- package/dist/src/api/sse.js.map +1 -0
- package/dist/src/bin/dev.d.ts +3 -0
- package/dist/src/bin/dev.d.ts.map +1 -0
- package/dist/src/bin/dev.js +76 -0
- package/dist/src/bin/dev.js.map +1 -0
- package/dist/src/bin/flags.d.ts +32 -0
- package/dist/src/bin/flags.d.ts.map +1 -0
- package/dist/src/bin/flags.js +55 -0
- package/dist/src/bin/flags.js.map +1 -0
- package/dist/src/bin/index.d.ts +3 -0
- package/dist/src/bin/index.d.ts.map +1 -0
- package/dist/src/bin/index.js +22 -0
- package/dist/src/bin/index.js.map +1 -0
- package/dist/src/bin/utils.d.ts +4 -0
- package/dist/src/bin/utils.d.ts.map +1 -0
- package/dist/src/bin/utils.js +52 -0
- package/dist/src/bin/utils.js.map +1 -0
- package/dist/src/client/index.d.ts +18 -0
- package/dist/src/client/index.d.ts.map +1 -0
- package/dist/src/client/index.js +150 -0
- package/dist/src/client/index.js.map +1 -0
- package/dist/src/config/config.d.ts +157 -0
- package/dist/src/config/config.d.ts.map +1 -0
- package/dist/src/config/config.js +65 -0
- package/dist/src/config/config.js.map +1 -0
- package/dist/src/config/env.d.ts +25 -0
- package/dist/src/config/env.d.ts.map +1 -0
- package/dist/src/config/env.js +21 -0
- package/dist/src/config/env.js.map +1 -0
- package/dist/src/contants.d.ts +4 -0
- package/dist/src/contants.d.ts.map +1 -0
- package/dist/src/contants.js +4 -0
- package/dist/src/contants.js.map +1 -0
- package/dist/src/db/actions/blocks.d.ts +44 -0
- package/dist/src/db/actions/blocks.d.ts.map +1 -0
- package/dist/src/db/actions/blocks.js +152 -0
- package/dist/src/db/actions/blocks.js.map +1 -0
- package/dist/src/db/actions/index.d.ts +2 -0
- package/dist/src/db/actions/index.d.ts.map +1 -0
- package/dist/src/db/actions/index.js +2 -0
- package/dist/src/db/actions/index.js.map +1 -0
- package/dist/src/db/actions/transactions.d.ts +11 -0
- package/dist/src/db/actions/transactions.d.ts.map +1 -0
- package/dist/src/db/actions/transactions.js +22 -0
- package/dist/src/db/actions/transactions.js.map +1 -0
- package/dist/src/db/client.d.ts +329 -0
- package/dist/src/db/client.d.ts.map +1 -0
- package/dist/src/db/client.js +108 -0
- package/dist/src/db/client.js.map +1 -0
- package/dist/src/db/column-types.d.ts +132 -0
- package/dist/src/db/column-types.d.ts.map +1 -0
- package/dist/src/db/column-types.js +86 -0
- package/dist/src/db/column-types.js.map +1 -0
- package/dist/src/db/encode.d.ts +10 -0
- package/dist/src/db/encode.d.ts.map +1 -0
- package/dist/src/db/encode.js +79 -0
- package/dist/src/db/encode.js.map +1 -0
- package/dist/src/db/migrate.d.ts +31 -0
- package/dist/src/db/migrate.d.ts.map +1 -0
- package/dist/src/db/migrate.js +147 -0
- package/dist/src/db/migrate.js.map +1 -0
- package/dist/src/db/schema/blocks.d.ts +369 -0
- package/dist/src/db/schema/blocks.d.ts.map +1 -0
- package/dist/src/db/schema/blocks.js +24 -0
- package/dist/src/db/schema/blocks.js.map +1 -0
- package/dist/src/db/schema/index.d.ts +1415 -0
- package/dist/src/db/schema/index.d.ts.map +1 -0
- package/dist/src/db/schema/index.js +18 -0
- package/dist/src/db/schema/index.js.map +1 -0
- package/dist/src/db/schema/transactions.d.ts +336 -0
- package/dist/src/db/schema/transactions.d.ts.map +1 -0
- package/dist/src/db/schema/transactions.js +33 -0
- package/dist/src/db/schema/transactions.js.map +1 -0
- package/dist/src/db/transaction.d.ts +7 -0
- package/dist/src/db/transaction.d.ts.map +1 -0
- package/dist/src/db/transaction.js +8 -0
- package/dist/src/db/transaction.js.map +1 -0
- package/dist/src/hooks/default-hooks.d.ts +2 -0
- package/dist/src/hooks/default-hooks.d.ts.map +1 -0
- package/dist/src/hooks/default-hooks.js +107 -0
- package/dist/src/hooks/default-hooks.js.map +1 -0
- package/dist/src/hooks/registry.d.ts +51 -0
- package/dist/src/hooks/registry.d.ts.map +1 -0
- package/dist/src/hooks/registry.js +32 -0
- package/dist/src/hooks/registry.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/indexer/backfill.d.ts +15 -0
- package/dist/src/indexer/backfill.d.ts.map +1 -0
- package/dist/src/indexer/backfill.js +95 -0
- package/dist/src/indexer/backfill.js.map +1 -0
- package/dist/src/indexer/live.d.ts +20 -0
- package/dist/src/indexer/live.d.ts.map +1 -0
- package/dist/src/indexer/live.js +51 -0
- package/dist/src/indexer/live.js.map +1 -0
- package/dist/src/indexer/process-block.d.ts +29 -0
- package/dist/src/indexer/process-block.d.ts.map +1 -0
- package/dist/src/indexer/process-block.js +91 -0
- package/dist/src/indexer/process-block.js.map +1 -0
- package/dist/src/indexer/queue-block.d.ts +18 -0
- package/dist/src/indexer/queue-block.d.ts.map +1 -0
- package/dist/src/indexer/queue-block.js +38 -0
- package/dist/src/indexer/queue-block.js.map +1 -0
- package/dist/src/indexer/reorg.d.ts +24 -0
- package/dist/src/indexer/reorg.d.ts.map +1 -0
- package/dist/src/indexer/reorg.js +83 -0
- package/dist/src/indexer/reorg.js.map +1 -0
- package/dist/src/indexer/runner.d.ts +14 -0
- package/dist/src/indexer/runner.d.ts.map +1 -0
- package/dist/src/indexer/runner.js +22 -0
- package/dist/src/indexer/runner.js.map +1 -0
- package/dist/src/rpc/client.d.ts +11 -0
- package/dist/src/rpc/client.d.ts.map +1 -0
- package/dist/src/rpc/client.js +18 -0
- package/dist/src/rpc/client.js.map +1 -0
- package/dist/src/rpc/get-block.d.ts +16 -0
- package/dist/src/rpc/get-block.d.ts.map +1 -0
- package/dist/src/rpc/get-block.js +77 -0
- package/dist/src/rpc/get-block.js.map +1 -0
- package/dist/src/rpc/get-logs.d.ts +11 -0
- package/dist/src/rpc/get-logs.d.ts.map +1 -0
- package/dist/src/rpc/get-logs.js +23 -0
- package/dist/src/rpc/get-logs.js.map +1 -0
- package/dist/src/schema.d.ts +3 -0
- package/dist/src/schema.d.ts.map +1 -0
- package/dist/src/schema.js +9 -0
- package/dist/src/schema.js.map +1 -0
- package/dist/src/types.d.ts +22 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +1 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils/bloom.d.ts +6 -0
- package/dist/src/utils/bloom.d.ts.map +1 -0
- package/dist/src/utils/bloom.js +30 -0
- package/dist/src/utils/bloom.js.map +1 -0
- package/dist/src/utils/build-conflict-columns.d.ts +4 -0
- package/dist/src/utils/build-conflict-columns.d.ts.map +1 -0
- package/dist/src/utils/build-conflict-columns.js +14 -0
- package/dist/src/utils/build-conflict-columns.js.map +1 -0
- package/dist/src/utils/common.d.ts +2 -0
- package/dist/src/utils/common.d.ts.map +1 -0
- package/dist/src/utils/common.js +4 -0
- package/dist/src/utils/common.js.map +1 -0
- package/dist/src/utils/cursor.d.ts +5 -0
- package/dist/src/utils/cursor.d.ts.map +1 -0
- package/dist/src/utils/cursor.js +8 -0
- package/dist/src/utils/cursor.js.map +1 -0
- package/dist/src/utils/format.d.ts +2 -0
- package/dist/src/utils/format.d.ts.map +1 -0
- package/dist/src/utils/format.js +16 -0
- package/dist/src/utils/format.js.map +1 -0
- package/dist/src/utils/hash.d.ts +9 -0
- package/dist/src/utils/hash.d.ts.map +1 -0
- package/dist/src/utils/hash.js +15 -0
- package/dist/src/utils/hash.js.map +1 -0
- package/dist/src/utils/json.d.ts +5 -0
- package/dist/src/utils/json.d.ts.map +1 -0
- package/dist/src/utils/json.js +11 -0
- package/dist/src/utils/json.js.map +1 -0
- package/dist/src/utils/logger.d.ts +11 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +111 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/shutdown.d.ts +9 -0
- package/dist/src/utils/shutdown.d.ts.map +1 -0
- package/dist/src/utils/shutdown.js +24 -0
- package/dist/src/utils/shutdown.js.map +1 -0
- package/dist/src/utils/timer.d.ts +6 -0
- package/dist/src/utils/timer.d.ts.map +1 -0
- package/dist/src/utils/timer.js +9 -0
- package/dist/src/utils/timer.js.map +1 -0
- package/dist/src/utils/types.d.ts +39 -0
- package/dist/src/utils/types.d.ts.map +1 -0
- package/dist/src/utils/types.js +1 -0
- package/dist/src/utils/types.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/hello/apps/foc-api/README.md +69 -0
- package/hello/apps/foc-api/biome.json +8 -0
- package/hello/apps/foc-api/index.html +13 -0
- package/hello/apps/foc-api/package.json +39 -0
- package/hello/apps/foc-api/public/vite.svg +1 -0
- package/hello/apps/foc-api/src/app.css +45 -0
- package/hello/apps/foc-api/src/app.tsx +43 -0
- package/hello/apps/foc-api/src/assets/Cloudflare_Logo.svg +51 -0
- package/hello/apps/foc-api/src/assets/react.svg +1 -0
- package/hello/apps/foc-api/src/client.ts +41 -0
- package/hello/apps/foc-api/src/components/account.tsx +100 -0
- package/hello/apps/foc-api/src/components/wallet-options.tsx +43 -0
- package/hello/apps/foc-api/src/index.css +68 -0
- package/hello/apps/foc-api/src/main.tsx +38 -0
- package/hello/apps/foc-api/src/vite-env.d.ts +1 -0
- package/hello/apps/foc-api/tsconfig.app.json +44 -0
- package/hello/apps/foc-api/tsconfig.json +17 -0
- package/hello/apps/foc-api/tsconfig.node.json +25 -0
- package/hello/apps/foc-api/tsconfig.worker.json +8 -0
- package/hello/apps/foc-api/vite.config.ts +8 -0
- package/hello/apps/foc-api/worker/capabilities.ts +25 -0
- package/hello/apps/foc-api/worker/index.ts +64 -0
- package/hello/apps/foc-api/worker/router.ts +35 -0
- package/hello/apps/foc-api/worker-configuration.d.ts +7357 -0
- package/hello/apps/foc-api/wrangler.jsonc +50 -0
- package/hello/apps/foc-app/README.md +69 -0
- package/hello/apps/foc-app/biome.json +8 -0
- package/hello/apps/foc-app/index.html +13 -0
- package/hello/apps/foc-app/package.json +39 -0
- package/hello/apps/foc-app/public/vite.svg +1 -0
- package/hello/apps/foc-app/src/app.css +45 -0
- package/hello/apps/foc-app/src/app.tsx +43 -0
- package/hello/apps/foc-app/src/assets/Cloudflare_Logo.svg +51 -0
- package/hello/apps/foc-app/src/assets/react.svg +1 -0
- package/hello/apps/foc-app/src/client.ts +41 -0
- package/hello/apps/foc-app/src/components/account.tsx +100 -0
- package/hello/apps/foc-app/src/components/wallet-options.tsx +43 -0
- package/hello/apps/foc-app/src/index.css +68 -0
- package/hello/apps/foc-app/src/main.tsx +38 -0
- package/hello/apps/foc-app/src/vite-env.d.ts +1 -0
- package/hello/apps/foc-app/tsconfig.app.json +44 -0
- package/hello/apps/foc-app/tsconfig.json +17 -0
- package/hello/apps/foc-app/tsconfig.node.json +25 -0
- package/hello/apps/foc-app/tsconfig.worker.json +8 -0
- package/hello/apps/foc-app/vite.config.ts +8 -0
- package/hello/apps/foc-app/worker/capabilities.ts +25 -0
- package/hello/apps/foc-app/worker/index.ts +64 -0
- package/hello/apps/foc-app/worker/router.ts +35 -0
- package/hello/apps/foc-app/worker-configuration.d.ts +7357 -0
- package/hello/apps/foc-app/wrangler.jsonc +50 -0
- package/hello/biome.json +50 -0
- package/hello/package.json +22 -0
- package/hello/pnpm-workspace.yaml +3 -0
- package/hello/tsconfig.json +37 -0
- package/package.json +78 -0
- package/src/api/index.ts +1 -0
- package/src/api/runner.ts +43 -0
- package/src/api/server.ts +38 -0
- package/src/api/sql-middleware.ts +131 -0
- package/src/api/sql.ts +149 -0
- package/src/api/sse.ts +12 -0
- package/src/bin/create.ts +199 -0
- package/src/bin/dev.ts +91 -0
- package/src/bin/flags.ts +65 -0
- package/src/bin/index.ts +28 -0
- package/src/bin/utils.ts +55 -0
- package/src/config/config.ts +221 -0
- package/src/config/env.ts +28 -0
- package/src/contants.ts +3 -0
- package/src/db/actions/blocks.ts +209 -0
- package/src/db/actions/index.ts +1 -0
- package/src/db/actions/transactions.ts +32 -0
- package/src/db/client.ts +186 -0
- package/src/db/column-types.ts +105 -0
- package/src/db/encode.ts +99 -0
- package/src/db/migrate.ts +222 -0
- package/src/db/schema/blocks.ts +24 -0
- package/src/db/schema/index.ts +21 -0
- package/src/db/schema/transactions.ts +39 -0
- package/src/db/transaction.ts +20 -0
- package/src/hooks/registry.ts +107 -0
- package/src/index.ts +9 -0
- package/src/indexer/backfill.ts +133 -0
- package/src/indexer/live.ts +76 -0
- package/src/indexer/process-block.ts +142 -0
- package/src/indexer/queue-block.ts +74 -0
- package/src/indexer/reorg.ts +120 -0
- package/src/indexer/runner.ts +35 -0
- package/src/rpc/client.ts +27 -0
- package/src/rpc/get-block.ts +100 -0
- package/src/rpc/get-logs.ts +38 -0
- package/src/schema.ts +10 -0
- package/src/types.ts +32 -0
- package/src/utils/bloom.ts +41 -0
- package/src/utils/build-conflict-columns.ts +26 -0
- package/src/utils/common.ts +3 -0
- package/src/utils/cursor.ts +7 -0
- package/src/utils/format.ts +18 -0
- package/src/utils/hash.ts +17 -0
- package/src/utils/json.ts +11 -0
- package/src/utils/logger.ts +149 -0
- package/src/utils/shutdown.ts +36 -0
- package/src/utils/timer.ts +8 -0
- package/src/utils/types.ts +87 -0
- package/template/biome.json +50 -0
- package/template/package.json +22 -0
- package/template/pnpm-workspace.yaml +3 -0
- package/template/tsconfig.json +37 -0
- package/tsconfig.json +8 -0
package/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# foxer
|
|
2
|
+
|
|
3
|
+
`foxer` is the core package for defining and running a Filecoin indexing/API service.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Typed config via `createConfig`.
|
|
8
|
+
- Contract/event indexing with hook registration.
|
|
9
|
+
- Drizzle schema and relation support.
|
|
10
|
+
- Runtime support for API + indexer bootstrap via CLI.
|
|
11
|
+
- Exposes API and schema helpers through subpath exports.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install foxer
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Entrypoint
|
|
20
|
+
|
|
21
|
+
- Package root: `foxer`
|
|
22
|
+
- Subpath exports: `foxer/api`, `foxer/schema`
|
|
23
|
+
- CLI binary: `foxer`
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Define config
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { createConfig } from 'foxer'
|
|
31
|
+
import { http } from 'viem'
|
|
32
|
+
|
|
33
|
+
export const config = createConfig({
|
|
34
|
+
client: {
|
|
35
|
+
transport: http(process.env.RPC_URL),
|
|
36
|
+
realtimeTransport: http(process.env.RPC_LIVE_URL),
|
|
37
|
+
chain: /* your viem chain */,
|
|
38
|
+
},
|
|
39
|
+
contracts: {
|
|
40
|
+
// contract definitions
|
|
41
|
+
},
|
|
42
|
+
hooks: ({ registry }) => {
|
|
43
|
+
// registry.on(...) handlers
|
|
44
|
+
},
|
|
45
|
+
hono: ({ db, logger }) => {
|
|
46
|
+
// return your Hono app
|
|
47
|
+
},
|
|
48
|
+
schema: {},
|
|
49
|
+
})
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Run locally
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
foxer dev
|
|
56
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { InternalConfig } from '../config/config.ts';
|
|
2
|
+
import type { Database } from '../db/client.ts';
|
|
3
|
+
import type { Logger } from '../utils/logger.ts';
|
|
4
|
+
export declare function bootstrapApiServer(options: {
|
|
5
|
+
db: Database;
|
|
6
|
+
config: InternalConfig;
|
|
7
|
+
logger: Logger;
|
|
8
|
+
port: number;
|
|
9
|
+
}): {
|
|
10
|
+
stop: () => void;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/api/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAGhD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,EAAE,EAAE,QAAQ,CAAA;IACZ,MAAM,EAAE,cAAc,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb,GAAG;IAAE,IAAI,EAAE,MAAM,IAAI,CAAA;CAAE,CA8BvB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { serve } from '@hono/node-server';
|
|
2
|
+
import shutdown from 'http-shutdown';
|
|
3
|
+
import { createApiServer } from "./server.js";
|
|
4
|
+
export function bootstrapApiServer(options) {
|
|
5
|
+
const app = createApiServer({
|
|
6
|
+
logger: options.logger,
|
|
7
|
+
db: options.db,
|
|
8
|
+
config: options.config,
|
|
9
|
+
});
|
|
10
|
+
const server = serve({
|
|
11
|
+
fetch: app.fetch,
|
|
12
|
+
port: options.port,
|
|
13
|
+
}, () => {
|
|
14
|
+
options.logger.info({ port: options.port }, 'api server listening');
|
|
15
|
+
});
|
|
16
|
+
const _server = shutdown(server);
|
|
17
|
+
return {
|
|
18
|
+
stop: () => {
|
|
19
|
+
_server.shutdown((error) => {
|
|
20
|
+
if (error) {
|
|
21
|
+
options.logger.error({ error }, 'api server shutdown failed');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
options.logger.info('api server shutdown complete');
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/api/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,OAAO,QAAQ,MAAM,eAAe,CAAA;AAIpC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C,MAAM,UAAU,kBAAkB,CAAC,OAKlC;IACC,MAAM,GAAG,GAAG,eAAe,CAAC;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,KAAK,CAClB;QACE,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,EACD,GAAG,EAAE;QACH,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,sBAAsB,CAAC,CAAA;IACrE,CAAC,CACF,CAAA;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;IAEhC,OAAO;QACL,IAAI,EAAE,GAAG,EAAE;YACT,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE;gBACzB,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,4BAA4B,CAAC,CAAA;oBAC7D,OAAM;gBACR,CAAC;gBACD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;YACrD,CAAC,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { type PinoLogger } from 'hono-pino';
|
|
3
|
+
import type { InternalConfig } from '../config/config.ts';
|
|
4
|
+
import type { Database } from '../db/client.ts';
|
|
5
|
+
import type { Logger } from '../utils/logger.ts';
|
|
6
|
+
/**
|
|
7
|
+
* Builds the Hono API server with health and sql endpoints.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createApiServer({ db, config, logger, }: {
|
|
10
|
+
db: Database;
|
|
11
|
+
config: InternalConfig;
|
|
12
|
+
logger: Logger;
|
|
13
|
+
}): Hono<{
|
|
14
|
+
Variables: {
|
|
15
|
+
logger: PinoLogger;
|
|
16
|
+
};
|
|
17
|
+
}, import("hono/types").BlankSchema, "/">;
|
|
18
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,KAAK,UAAU,EAAc,MAAM,WAAW,CAAA;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEhD;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,MAAM,EACN,MAAM,GACP,EAAE;IACD,EAAE,EAAE,QAAQ,CAAA;IACZ,MAAM,EAAE,cAAc,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;CACf;eACmC;QAAE,MAAM,EAAE,UAAU,CAAA;KAAE;0CAmBzD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { pinoLogger } from 'hono-pino';
|
|
3
|
+
/**
|
|
4
|
+
* Builds the Hono API server with health and sql endpoints.
|
|
5
|
+
*/
|
|
6
|
+
export function createApiServer({ db, config, logger, }) {
|
|
7
|
+
const app = new Hono();
|
|
8
|
+
app.use(pinoLogger({
|
|
9
|
+
pino: logger,
|
|
10
|
+
}));
|
|
11
|
+
app.get('/health', async (c) => {
|
|
12
|
+
const latest = (await db.$prepared.getLatestBlock.execute())[0]?.number ?? null;
|
|
13
|
+
return c.json({
|
|
14
|
+
ok: true,
|
|
15
|
+
latestIndexedBlock: latest?.toString() ?? null,
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
app.route('/', config.hono({ logger, db }));
|
|
19
|
+
return app;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAmB,UAAU,EAAE,MAAM,WAAW,CAAA;AAKvD;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,EAAE,EACF,MAAM,EACN,MAAM,GAKP;IACC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAyC,CAAA;IAE7D,GAAG,CAAC,GAAG,CACL,UAAU,CAAC;QACT,IAAI,EAAE,MAAM;KACb,CAAC,CACH,CAAA;IAED,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC7B,MAAM,MAAM,GACV,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,IAAI,CAAA;QAClE,OAAO,CAAC,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,IAAI;YACR,kBAAkB,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,IAAI;SAC/C,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IAC3C,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Database } from '../db/client.ts';
|
|
2
|
+
import type { Logger } from '../utils/logger.ts';
|
|
3
|
+
export declare function sqlMiddleware({ db, logger, }: {
|
|
4
|
+
db: Database;
|
|
5
|
+
logger: Logger;
|
|
6
|
+
}): import("hono").MiddlewareHandler<any, string, {}, Response>;
|
|
7
|
+
//# sourceMappingURL=sql-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-middleware.d.ts","sourceRoot":"","sources":["../../../src/api/sql-middleware.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAMhD,wBAAgB,aAAa,CAAC,EAC5B,EAAE,EACF,MAAM,GACP,EAAE;IACD,EAAE,EAAE,QAAQ,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf,+DAgHA"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { createMiddleware } from 'hono/factory';
|
|
2
|
+
import { streamSSE } from 'hono/streaming';
|
|
3
|
+
import postgres from 'postgres';
|
|
4
|
+
import { PUBLICATION_NAME } from "../contants.js";
|
|
5
|
+
import { executeSql, validateSql } from "./sql.js";
|
|
6
|
+
import { sseError } from "./sse.js";
|
|
7
|
+
const MAX_LIVE_QUERIES = 1000;
|
|
8
|
+
export function sqlMiddleware({ db, logger, }) {
|
|
9
|
+
let pg;
|
|
10
|
+
const databaseUrl = process.env.DATABASE_URL;
|
|
11
|
+
if (databaseUrl && typeof databaseUrl === 'string') {
|
|
12
|
+
// TODO: kill gracefully
|
|
13
|
+
pg = postgres(databaseUrl, {
|
|
14
|
+
publications: PUBLICATION_NAME,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
let liveQueryCount = 0;
|
|
18
|
+
return createMiddleware(async (c, next) => {
|
|
19
|
+
// SQL over HTTP endpoint
|
|
20
|
+
if (c.req.path === '/sql/db') {
|
|
21
|
+
const queryString = c.req.query('sql');
|
|
22
|
+
if (!queryString) {
|
|
23
|
+
return c.json({ error: 'sql query is required' }, 400);
|
|
24
|
+
}
|
|
25
|
+
const query = JSON.parse(queryString);
|
|
26
|
+
const result = await validateSql(query);
|
|
27
|
+
if (result.error) {
|
|
28
|
+
return c.json({ error: result.error.message }, 400);
|
|
29
|
+
}
|
|
30
|
+
const dbResult = await executeSql({ db, query });
|
|
31
|
+
if (dbResult.error) {
|
|
32
|
+
return c.json({ error: dbResult.error.message }, 500);
|
|
33
|
+
}
|
|
34
|
+
return c.json(dbResult.result, 200);
|
|
35
|
+
}
|
|
36
|
+
// Live SQL over SSE endpoint
|
|
37
|
+
if (c.req.path === '/sql/live') {
|
|
38
|
+
if (liveQueryCount >= MAX_LIVE_QUERIES) {
|
|
39
|
+
return sseError(c, 'Too many live queries');
|
|
40
|
+
}
|
|
41
|
+
const queryString = c.req.query('sql');
|
|
42
|
+
if (!queryString) {
|
|
43
|
+
return sseError(c, 'SQL query is required');
|
|
44
|
+
}
|
|
45
|
+
const query = JSON.parse(queryString);
|
|
46
|
+
const result = await validateSql(query);
|
|
47
|
+
if (result.error) {
|
|
48
|
+
return sseError(c, result.error.message);
|
|
49
|
+
}
|
|
50
|
+
const tables = result.result;
|
|
51
|
+
const dbResult = await executeSql({ db, query });
|
|
52
|
+
if (dbResult.error) {
|
|
53
|
+
return sseError(c, dbResult.error.message);
|
|
54
|
+
}
|
|
55
|
+
if (!pg) {
|
|
56
|
+
return sseError(c, 'Database connection not established. Please check your DATABASE_URL environment variable.');
|
|
57
|
+
}
|
|
58
|
+
const subscriptions = [];
|
|
59
|
+
liveQueryCount++;
|
|
60
|
+
return streamSSE(c, async (stream) => {
|
|
61
|
+
stream.onAbort(() => {
|
|
62
|
+
liveQueryCount--;
|
|
63
|
+
logger.trace('stream aborted');
|
|
64
|
+
subscriptions.forEach((unsubscribe) => {
|
|
65
|
+
unsubscribe();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
stream.writeSSE({
|
|
69
|
+
data: JSON.stringify(dbResult.result),
|
|
70
|
+
});
|
|
71
|
+
for (const table of tables) {
|
|
72
|
+
const sub = await pg.subscribe(`*:${table}`, async () => {
|
|
73
|
+
const dbResult = await executeSql({ db, query });
|
|
74
|
+
stream.writeSSE({
|
|
75
|
+
data: JSON.stringify(dbResult.result),
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
subscriptions.push(sub.unsubscribe);
|
|
79
|
+
}
|
|
80
|
+
while (stream.closed === false && stream.aborted === false) {
|
|
81
|
+
// keep the stream alive
|
|
82
|
+
await stream.sleep(1000);
|
|
83
|
+
}
|
|
84
|
+
}, (error) => {
|
|
85
|
+
logger.error({ error }, 'stream error');
|
|
86
|
+
subscriptions.forEach((unsubscribe) => {
|
|
87
|
+
unsubscribe();
|
|
88
|
+
});
|
|
89
|
+
return Promise.resolve(undefined);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return next();
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=sql-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-middleware.js","sourceRoot":"","sources":["../../../src/api/sql-middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Node } from '@libpg-query/parser';
|
|
2
|
+
import type { QueryWithTypings } from 'drizzle-orm';
|
|
3
|
+
import type { Database } from '../db/client';
|
|
4
|
+
import type { MaybeResult } from '../types';
|
|
5
|
+
export declare function parseSql(sql: string): Promise<MaybeResult<{
|
|
6
|
+
node: Node;
|
|
7
|
+
tables: string[];
|
|
8
|
+
}>>;
|
|
9
|
+
export declare function validateSql(query: QueryWithTypings): Promise<MaybeResult<string[]>>;
|
|
10
|
+
export declare function executeSql({ db, query, }: {
|
|
11
|
+
db: Database;
|
|
12
|
+
query: QueryWithTypings;
|
|
13
|
+
}): Promise<MaybeResult<unknown>>;
|
|
14
|
+
//# sourceMappingURL=sql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../../src/api/sql.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,IAAI,EAGV,MAAM,qBAAqB,CAAA;AAG5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAK3C,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,WAAW,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAAC,CAiCxD;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAwDhC;AAED,wBAAsB,UAAU,CAAC,EAC/B,EAAE,EACF,KAAK,GACN,EAAE;IACD,EAAE,EAAE,QAAQ,CAAA;IACZ,KAAK,EAAE,gBAAgB,CAAA;CACxB,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CA4BhC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { PGlite } from '@electric-sql/pglite';
|
|
2
|
+
import { parse, } from '@libpg-query/parser';
|
|
3
|
+
import { walk } from '@pgsql/traverse';
|
|
4
|
+
import { Pool } from 'pg';
|
|
5
|
+
// biome-ignore lint/style/noNonNullAssertion: we know the node is not null
|
|
6
|
+
const getNodeType = (node) => Object.keys(node)[0];
|
|
7
|
+
export async function parseSql(sql) {
|
|
8
|
+
let result;
|
|
9
|
+
const tables = [];
|
|
10
|
+
// Using a visitor object (recommended for multiple node types)
|
|
11
|
+
const visitor = {
|
|
12
|
+
RangeVar: (path) => {
|
|
13
|
+
tables.push(path.node.relname);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
try {
|
|
17
|
+
result = (await parse(sql));
|
|
18
|
+
walk(result, visitor);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
return { error: new Error('Failed to parse SQL', { cause: error }) };
|
|
22
|
+
}
|
|
23
|
+
if (result?.stmts.length === 0) {
|
|
24
|
+
return { error: new Error('No statement found') };
|
|
25
|
+
}
|
|
26
|
+
if (result?.stmts?.length && result.stmts.length > 1) {
|
|
27
|
+
return { error: new Error('Only one statement is allowed') };
|
|
28
|
+
}
|
|
29
|
+
const stmt = result?.stmts[0];
|
|
30
|
+
if (stmt?.stmt == null) {
|
|
31
|
+
return { error: new Error('Invalid statement') };
|
|
32
|
+
}
|
|
33
|
+
const node = stmt.stmt;
|
|
34
|
+
return { result: { node, tables } };
|
|
35
|
+
}
|
|
36
|
+
export async function validateSql(query) {
|
|
37
|
+
const { sql, params } = query;
|
|
38
|
+
const result = await parseSql(sql);
|
|
39
|
+
if (result.error) {
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
const { node, tables } = result.result;
|
|
43
|
+
const nodeType = getNodeType(node);
|
|
44
|
+
if (nodeType !== 'SelectStmt') {
|
|
45
|
+
return { error: new Error('Only select statements are allowed') };
|
|
46
|
+
}
|
|
47
|
+
if (!('SelectStmt' in node)) {
|
|
48
|
+
return { error: new Error('Invalid statement') };
|
|
49
|
+
}
|
|
50
|
+
const selectStmt = node.SelectStmt;
|
|
51
|
+
if (selectStmt.lockingClause || selectStmt.intoClause) {
|
|
52
|
+
return { error: new Error('Locking or into clauses are not allowed') };
|
|
53
|
+
}
|
|
54
|
+
if (selectStmt.withClause?.recursive) {
|
|
55
|
+
return { error: new Error('Recursive with clauses are not allowed') };
|
|
56
|
+
}
|
|
57
|
+
if (!selectStmt.limitCount) {
|
|
58
|
+
return { error: new Error('Limit is required') };
|
|
59
|
+
}
|
|
60
|
+
let limit;
|
|
61
|
+
if ('ParamRef' in selectStmt.limitCount) {
|
|
62
|
+
const limitIndex = selectStmt.limitCount.ParamRef.number;
|
|
63
|
+
const _limit = params[limitIndex - 1];
|
|
64
|
+
if (typeof _limit === 'number') {
|
|
65
|
+
limit = _limit;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if ('A_Const' in selectStmt.limitCount) {
|
|
69
|
+
const aConst = selectStmt.limitCount.A_Const;
|
|
70
|
+
limit = aConst.ival?.ival ?? 0;
|
|
71
|
+
}
|
|
72
|
+
if (typeof limit !== 'number' || limit < 1) {
|
|
73
|
+
return {
|
|
74
|
+
error: new Error('Limit is required and must be a number greater than 0'),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (limit > 100) {
|
|
78
|
+
return { error: new Error('Limit is too large (max 100)') };
|
|
79
|
+
}
|
|
80
|
+
return { result: tables };
|
|
81
|
+
}
|
|
82
|
+
export async function executeSql({ db, query, }) {
|
|
83
|
+
try {
|
|
84
|
+
let dbResult;
|
|
85
|
+
if (db.$client instanceof PGlite) {
|
|
86
|
+
dbResult = await db._.session
|
|
87
|
+
.prepareQuery(query, undefined, undefined, false)
|
|
88
|
+
.execute();
|
|
89
|
+
}
|
|
90
|
+
if (db.$client instanceof Pool) {
|
|
91
|
+
dbResult = await db.transaction((tx) => {
|
|
92
|
+
return tx._.session
|
|
93
|
+
.prepareQuery(query, undefined, undefined, false)
|
|
94
|
+
.execute();
|
|
95
|
+
}, { accessMode: 'read only' });
|
|
96
|
+
}
|
|
97
|
+
if (dbResult == null) {
|
|
98
|
+
return { error: new Error('Empty result') };
|
|
99
|
+
}
|
|
100
|
+
return { result: dbResult };
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
return {
|
|
104
|
+
error: error instanceof Error ? error : new Error('Unknown error'),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["../../../src/api/sql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/api/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGnC,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAQnD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { streamSSE } from 'hono/streaming';
|
|
2
|
+
export function sseError(c, message) {
|
|
3
|
+
return streamSSE(c, async (stream) => {
|
|
4
|
+
await stream.writeSSE({
|
|
5
|
+
event: 'error',
|
|
6
|
+
data: message,
|
|
7
|
+
});
|
|
8
|
+
return stream.close();
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=sse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../../src/api/sse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,UAAU,QAAQ,CAAC,CAAU,EAAE,OAAe;IAClD,OAAO,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACnC,MAAM,MAAM,CAAC,QAAQ,CAAC;YACpB,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,OAAO;SACd,CAAC,CAAA;QACF,OAAO,MAAM,CAAC,KAAK,EAAE,CAAA;IACvB,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/bin/dev.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAW,MAAM,OAAO,CAAA;AAc7C,eAAO,MAAM,GAAG,EAAE,OA0EjB,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { command } from 'cleye';
|
|
4
|
+
import { gracefulExit } from 'exit-hook';
|
|
5
|
+
import { bootstrapApiServer } from "../api/runner.js";
|
|
6
|
+
import { createEnv } from "../config/env.js";
|
|
7
|
+
import { createDatabase } from "../db/client.js";
|
|
8
|
+
import { runMigrations } from "../db/migrate.js";
|
|
9
|
+
import * as InternalSchema from "../db/schema/index.js";
|
|
10
|
+
import { HookRegistry } from "../hooks/registry.js";
|
|
11
|
+
import { bootstrapIndexer } from "../indexer/runner.js";
|
|
12
|
+
import { createLogger } from "../utils/logger.js";
|
|
13
|
+
import { createExit, registerUnhandled } from "../utils/shutdown.js";
|
|
14
|
+
import { globalFlags } from "./flags.js";
|
|
15
|
+
import { loadConfig } from "./utils.js";
|
|
16
|
+
export const dev = command({
|
|
17
|
+
name: 'dev',
|
|
18
|
+
flags: { ...globalFlags },
|
|
19
|
+
help: {
|
|
20
|
+
description: 'Start the development server with hot reloading',
|
|
21
|
+
},
|
|
22
|
+
}, async (argv) => {
|
|
23
|
+
const logger = createLogger({
|
|
24
|
+
level: argv.flags.logLevel,
|
|
25
|
+
mode: argv.flags.logMode,
|
|
26
|
+
});
|
|
27
|
+
registerUnhandled({ logger });
|
|
28
|
+
if (!fs.existsSync(path.join(argv.flags.root, '.env.local'))) {
|
|
29
|
+
logger.warn({
|
|
30
|
+
msg: 'Local environment file (.env.local) not found',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const env = createEnv(logger);
|
|
35
|
+
const config = await loadConfig(logger, argv.flags.root, argv.flags.config);
|
|
36
|
+
const dbContext = createDatabase({
|
|
37
|
+
env,
|
|
38
|
+
schema: { ...config.schema, ...InternalSchema.schema },
|
|
39
|
+
relations: { ...config.relations, ...InternalSchema.relations },
|
|
40
|
+
});
|
|
41
|
+
await runMigrations({
|
|
42
|
+
dbContext,
|
|
43
|
+
folder: path.resolve(argv.flags.root, config.drizzleFolder),
|
|
44
|
+
logger,
|
|
45
|
+
});
|
|
46
|
+
const registry = new HookRegistry();
|
|
47
|
+
config.hooks({ registry });
|
|
48
|
+
const [api, indexer] = await Promise.all([
|
|
49
|
+
bootstrapApiServer({
|
|
50
|
+
db: dbContext.db,
|
|
51
|
+
config,
|
|
52
|
+
logger,
|
|
53
|
+
port: argv.flags.port,
|
|
54
|
+
}),
|
|
55
|
+
bootstrapIndexer({
|
|
56
|
+
logger,
|
|
57
|
+
db: dbContext.db,
|
|
58
|
+
registry,
|
|
59
|
+
config,
|
|
60
|
+
}),
|
|
61
|
+
]);
|
|
62
|
+
createExit({
|
|
63
|
+
logger,
|
|
64
|
+
stop: async () => {
|
|
65
|
+
indexer.stop();
|
|
66
|
+
api.stop();
|
|
67
|
+
await dbContext.close();
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
logger.error({ error }, 'dev server failed');
|
|
73
|
+
gracefulExit(1);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../../src/bin/dev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
declare const possibleLogModes: readonly ["pretty", "json"];
|
|
2
|
+
type LogModes = (typeof possibleLogModes)[number];
|
|
3
|
+
declare const LogLevels: readonly ["trace", "debug", "info", "warn", "error", "fatal", "silent"];
|
|
4
|
+
type LogLevels = (typeof LogLevels)[number];
|
|
5
|
+
export declare const globalFlags: {
|
|
6
|
+
readonly config: {
|
|
7
|
+
readonly type: StringConstructor;
|
|
8
|
+
readonly description: "The path to the config file";
|
|
9
|
+
};
|
|
10
|
+
readonly root: {
|
|
11
|
+
readonly type: (dir: string) => string;
|
|
12
|
+
readonly description: "The root directory of the project";
|
|
13
|
+
readonly default: string;
|
|
14
|
+
};
|
|
15
|
+
readonly logLevel: {
|
|
16
|
+
readonly type: (logLevel: LogLevels) => "fatal" | "error" | "warn" | "info" | "debug" | "trace" | "silent";
|
|
17
|
+
readonly description: "The log level to use";
|
|
18
|
+
readonly default: "fatal" | "error" | "warn" | "info" | "debug" | "trace" | "silent";
|
|
19
|
+
};
|
|
20
|
+
readonly logMode: {
|
|
21
|
+
readonly type: (logMode: LogModes) => "json" | "pretty";
|
|
22
|
+
readonly description: "The log mode to use";
|
|
23
|
+
readonly default: "json" | "pretty";
|
|
24
|
+
};
|
|
25
|
+
readonly port: {
|
|
26
|
+
readonly type: NumberConstructor;
|
|
27
|
+
readonly description: "The port to use for the API server";
|
|
28
|
+
readonly default: number;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../../src/bin/flags.ts"],"names":[],"mappings":"AAMA,QAAA,MAAM,gBAAgB,6BAA8B,CAAA;AAEpD,KAAK,QAAQ,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AAWjD,QAAA,MAAM,SAAS,yEAQL,CAAA;AACV,KAAK,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;AAU3C,eAAO,MAAM,WAAW;;;;;;6BApCL,MAAM;;;;;kCA6BG,SAAS;;;;;iCApBX,QAAQ;;;;;;;;;CAqDxB,CAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
const Root = (dir) => {
|
|
3
|
+
return path.resolve(dir);
|
|
4
|
+
};
|
|
5
|
+
const possibleLogModes = ['pretty', 'json'];
|
|
6
|
+
// Custom type function
|
|
7
|
+
const LogMode = (logMode) => {
|
|
8
|
+
if (!possibleLogModes.includes(logMode)) {
|
|
9
|
+
throw new Error(`Invalid log mode: "${logMode}"`);
|
|
10
|
+
}
|
|
11
|
+
return logMode;
|
|
12
|
+
};
|
|
13
|
+
const LogLevels = [
|
|
14
|
+
'trace',
|
|
15
|
+
'debug',
|
|
16
|
+
'info',
|
|
17
|
+
'warn',
|
|
18
|
+
'error',
|
|
19
|
+
'fatal',
|
|
20
|
+
'silent',
|
|
21
|
+
];
|
|
22
|
+
// Custom type function
|
|
23
|
+
const LogLevel = (logLevel) => {
|
|
24
|
+
if (!LogLevels.includes(logLevel)) {
|
|
25
|
+
throw new Error(`Invalid log level: "${logLevel}"`);
|
|
26
|
+
}
|
|
27
|
+
return logLevel;
|
|
28
|
+
};
|
|
29
|
+
export const globalFlags = {
|
|
30
|
+
config: {
|
|
31
|
+
type: String,
|
|
32
|
+
description: 'The path to the config file',
|
|
33
|
+
},
|
|
34
|
+
root: {
|
|
35
|
+
type: Root,
|
|
36
|
+
description: 'The root directory of the project',
|
|
37
|
+
default: process.cwd(),
|
|
38
|
+
},
|
|
39
|
+
logLevel: {
|
|
40
|
+
type: LogLevel,
|
|
41
|
+
description: 'The log level to use',
|
|
42
|
+
default: LogLevel(process.env.LOG_LEVEL ?? 'info'),
|
|
43
|
+
},
|
|
44
|
+
logMode: {
|
|
45
|
+
type: LogMode,
|
|
46
|
+
description: 'The log mode to use',
|
|
47
|
+
default: LogMode(process.env.NODE_ENV !== 'production' ? 'pretty' : 'json'),
|
|
48
|
+
},
|
|
49
|
+
port: {
|
|
50
|
+
type: Number,
|
|
51
|
+
description: 'The port to use for the API server',
|
|
52
|
+
default: process.env.PORT ? Number(process.env.PORT) : 4200,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flags.js","sourceRoot":"","sources":["../../../src/bin/flags.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,EAAE;IAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AAC1B,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAU,CAAA;AAIpD,uBAAuB;AACvB,MAAM,OAAO,GAAG,CAAC,OAAiB,EAAE,EAAE;IACpC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,sBAAsB,OAAO,GAAG,CAAC,CAAA;IACnD,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,SAAS,GAAG;IAChB,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;CACA,CAAA;AAGV,uBAAuB;AACvB,MAAM,QAAQ,GAAG,CAAC,QAAmB,EAAE,EAAE;IACvC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,GAAG,CAAC,CAAA;IACrD,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AACD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,6BAA6B;KAC3C;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,mCAAmC;QAChD,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE;KACvB;IAED,QAAQ,EAAE;QACR,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,sBAAsB;QACnC,OAAO,EAAE,QAAQ,CAAE,OAAO,CAAC,GAAG,CAAC,SAAuB,IAAI,MAAM,CAAC;KAClE;IACD,OAAO,EAAE;QACP,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,qBAAqB;QAClC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;KAC5E;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,oCAAoC;QACjD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;KAC5D;CACO,CAAA"}
|