@hatk/hatk 0.0.1-alpha.23 → 0.0.1-alpha.25
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/dist/adapter.d.ts +19 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +94 -0
- package/dist/backfill.d.ts.map +1 -1
- package/dist/backfill.js +12 -0
- package/dist/cli.js +186 -66
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +5 -1
- package/dist/dev-entry.d.ts +8 -0
- package/dist/dev-entry.d.ts.map +1 -0
- package/dist/dev-entry.js +109 -0
- package/dist/feeds.d.ts +4 -0
- package/dist/feeds.d.ts.map +1 -1
- package/dist/feeds.js +41 -2
- package/dist/hooks.d.ts +7 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +11 -1
- package/dist/labels.d.ts +14 -0
- package/dist/labels.d.ts.map +1 -1
- package/dist/labels.js +13 -1
- package/dist/main.js +49 -17
- package/dist/oauth/server.d.ts +2 -0
- package/dist/oauth/server.d.ts.map +1 -1
- package/dist/oauth/server.js +91 -1
- package/dist/oauth/session.d.ts +9 -0
- package/dist/oauth/session.d.ts.map +1 -0
- package/dist/oauth/session.js +65 -0
- package/dist/opengraph.d.ts +10 -0
- package/dist/opengraph.d.ts.map +1 -1
- package/dist/opengraph.js +102 -4
- package/dist/pds-proxy.d.ts +39 -0
- package/dist/pds-proxy.d.ts.map +1 -0
- package/dist/pds-proxy.js +173 -0
- package/dist/renderer.d.ts +27 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +46 -0
- package/dist/response.d.ts +16 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/response.js +69 -0
- package/dist/scanner.d.ts +21 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +88 -0
- package/dist/server-init.d.ts +8 -0
- package/dist/server-init.d.ts.map +1 -0
- package/dist/server-init.js +59 -0
- package/dist/server.d.ts +26 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +473 -616
- package/dist/setup.d.ts +7 -0
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +13 -1
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +12 -22
- package/dist/vite-plugin.d.ts +1 -1
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.js +245 -75
- package/dist/xrpc.d.ts +13 -0
- package/dist/xrpc.d.ts.map +1 -1
- package/dist/xrpc.js +87 -1
- package/package.json +8 -5
package/dist/scanner.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { resolve, relative } from 'node:path';
|
|
10
|
+
import { readdirSync, statSync, existsSync } from 'node:fs';
|
|
11
|
+
import { log } from "./logger.js";
|
|
12
|
+
/** Recursively collect .ts/.js files, skipping _ prefixed and dot files */
|
|
13
|
+
function walkDir(dir) {
|
|
14
|
+
const results = [];
|
|
15
|
+
try {
|
|
16
|
+
for (const entry of readdirSync(dir)) {
|
|
17
|
+
if (entry.startsWith('_') || entry.startsWith('.'))
|
|
18
|
+
continue;
|
|
19
|
+
const full = resolve(dir, entry);
|
|
20
|
+
if (statSync(full).isDirectory()) {
|
|
21
|
+
results.push(...walkDir(full));
|
|
22
|
+
}
|
|
23
|
+
else if (entry.endsWith('.ts') || entry.endsWith('.js')) {
|
|
24
|
+
results.push(full);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch { }
|
|
29
|
+
return results.sort();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Scan a directory for hatk server modules.
|
|
33
|
+
* Each file's default export is inspected for a `__type` tag.
|
|
34
|
+
*/
|
|
35
|
+
export async function scanServerDir(serverDir) {
|
|
36
|
+
const result = {
|
|
37
|
+
feeds: [],
|
|
38
|
+
queries: [],
|
|
39
|
+
procedures: [],
|
|
40
|
+
hooks: [],
|
|
41
|
+
setup: [],
|
|
42
|
+
labels: [],
|
|
43
|
+
og: [],
|
|
44
|
+
renderer: null,
|
|
45
|
+
};
|
|
46
|
+
if (!existsSync(serverDir))
|
|
47
|
+
return result;
|
|
48
|
+
const files = walkDir(serverDir);
|
|
49
|
+
for (const filePath of files) {
|
|
50
|
+
const name = relative(serverDir, filePath).replace(/\.(ts|js)$/, '');
|
|
51
|
+
const mod = await import(__rewriteRelativeImportExtension(/* @vite-ignore */ `${filePath}?t=${Date.now()}`));
|
|
52
|
+
const exported = mod.default;
|
|
53
|
+
if (!exported) {
|
|
54
|
+
log(`[scanner] ${name}: no default export, skipping`);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const entry = { path: filePath, name, mod: exported };
|
|
58
|
+
switch (exported.__type) {
|
|
59
|
+
case 'feed':
|
|
60
|
+
result.feeds.push(entry);
|
|
61
|
+
break;
|
|
62
|
+
case 'query':
|
|
63
|
+
result.queries.push(entry);
|
|
64
|
+
break;
|
|
65
|
+
case 'procedure':
|
|
66
|
+
result.procedures.push(entry);
|
|
67
|
+
break;
|
|
68
|
+
case 'hook':
|
|
69
|
+
result.hooks.push(entry);
|
|
70
|
+
break;
|
|
71
|
+
case 'setup':
|
|
72
|
+
result.setup.push(entry);
|
|
73
|
+
break;
|
|
74
|
+
case 'labels':
|
|
75
|
+
result.labels.push(entry);
|
|
76
|
+
break;
|
|
77
|
+
case 'og':
|
|
78
|
+
result.og.push(entry);
|
|
79
|
+
break;
|
|
80
|
+
case 'renderer':
|
|
81
|
+
result.renderer = entry;
|
|
82
|
+
break;
|
|
83
|
+
default:
|
|
84
|
+
log(`[scanner] ${name}: no recognized __type tag, skipping`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scan the server/ directory and register all discovered handlers.
|
|
3
|
+
* Setup scripts run immediately (in sorted order).
|
|
4
|
+
*/
|
|
5
|
+
export declare function initServer(serverDir: string, opts?: {
|
|
6
|
+
skipSetup?: boolean;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=server-init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-init.d.ts","sourceRoot":"","sources":["../src/server-init.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDjG"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { log } from "./logger.js";
|
|
3
|
+
import { scanServerDir } from "./scanner.js";
|
|
4
|
+
import { registerFeed, listFeeds } from "./feeds.js";
|
|
5
|
+
import { registerXrpcHandler, listXrpc } from "./xrpc.js";
|
|
6
|
+
import { registerLabelModule, getLabelDefinitions } from "./labels.js";
|
|
7
|
+
import { registerOgHandler } from "./opengraph.js";
|
|
8
|
+
import { registerHook } from "./hooks.js";
|
|
9
|
+
import { runSetupHandler } from "./setup.js";
|
|
10
|
+
import { registerRenderer } from "./renderer.js";
|
|
11
|
+
/**
|
|
12
|
+
* Scan the server/ directory and register all discovered handlers.
|
|
13
|
+
* Setup scripts run immediately (in sorted order).
|
|
14
|
+
*/
|
|
15
|
+
export async function initServer(serverDir, opts) {
|
|
16
|
+
if (!existsSync(serverDir)) {
|
|
17
|
+
log(`[server] No server/ directory found, skipping`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const scanned = await scanServerDir(serverDir);
|
|
21
|
+
// 1. Run setup scripts first (sorted by name) — skipped in test context
|
|
22
|
+
if (!opts?.skipSetup) {
|
|
23
|
+
for (const entry of scanned.setup.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
24
|
+
await runSetupHandler(entry.name, entry.mod.handler);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// 2. Register feeds
|
|
28
|
+
for (const entry of scanned.feeds) {
|
|
29
|
+
const feedName = entry.name.includes('/') ? entry.name.split('/').pop() : entry.name;
|
|
30
|
+
registerFeed(feedName, entry.mod);
|
|
31
|
+
}
|
|
32
|
+
// 3. Register XRPC handlers
|
|
33
|
+
for (const entry of scanned.queries) {
|
|
34
|
+
registerXrpcHandler(entry.mod.nsid, entry.mod);
|
|
35
|
+
}
|
|
36
|
+
for (const entry of scanned.procedures) {
|
|
37
|
+
registerXrpcHandler(entry.mod.nsid, entry.mod);
|
|
38
|
+
}
|
|
39
|
+
// 4. Register hooks
|
|
40
|
+
for (const entry of scanned.hooks) {
|
|
41
|
+
registerHook(entry.mod.event, entry.mod.handler);
|
|
42
|
+
}
|
|
43
|
+
// 5. Register labels
|
|
44
|
+
for (const entry of scanned.labels) {
|
|
45
|
+
registerLabelModule(entry.name, entry.mod);
|
|
46
|
+
}
|
|
47
|
+
// 6. Register OG handlers
|
|
48
|
+
for (const entry of scanned.og) {
|
|
49
|
+
registerOgHandler(entry.mod);
|
|
50
|
+
}
|
|
51
|
+
// 7. Register renderer
|
|
52
|
+
if (scanned.renderer) {
|
|
53
|
+
registerRenderer(scanned.renderer.mod.handler);
|
|
54
|
+
}
|
|
55
|
+
log(`[server] Initialized from server/ directory:`);
|
|
56
|
+
log(` Feeds: ${listFeeds().map((f) => f.name).join(', ') || 'none'}`);
|
|
57
|
+
log(` XRPC: ${listXrpc().join(', ') || 'none'}`);
|
|
58
|
+
log(` Labels: ${getLabelDefinitions().length} definitions`);
|
|
59
|
+
}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
|
-
import { type Server, type IncomingMessage } from 'node:http';
|
|
2
1
|
import type { OAuthConfig } from './config.ts';
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Register built-in dev.hatk.* XRPC handlers in the handler registry.
|
|
4
|
+
* This makes them available to callXrpc() for use in SSR and server code.
|
|
5
|
+
*/
|
|
6
|
+
export declare function registerCoreHandlers(collections: string[], oauth: OAuthConfig | null): void;
|
|
7
|
+
export interface HandlerConfig {
|
|
8
|
+
collections: string[];
|
|
9
|
+
publicDir: string | null;
|
|
10
|
+
oauth: OAuthConfig | null;
|
|
11
|
+
admins: string[];
|
|
12
|
+
renderer?: (request: Request, manifest: any) => Promise<{
|
|
13
|
+
html: string;
|
|
14
|
+
head?: string;
|
|
15
|
+
}>;
|
|
16
|
+
resolveViewer?: (request: Request) => {
|
|
17
|
+
did: string;
|
|
18
|
+
} | null;
|
|
19
|
+
onResync?: () => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create a Web Standard request handler for all hatk routes.
|
|
23
|
+
* Returns a pure function: (Request) → Promise<Response>
|
|
24
|
+
*/
|
|
25
|
+
export declare function createHandler(config: HandlerConfig): (request: Request) => Promise<Response>;
|
|
26
|
+
export declare function startServer(port: number, collections: string[], publicDir: string | null, oauth: OAuthConfig | null, admins?: string[], resolveViewer?: (request: Request) => {
|
|
4
27
|
did: string;
|
|
5
|
-
} | null, onResync?: () => void): Server;
|
|
28
|
+
} | null, onResync?: () => void): import('node:http').Server;
|
|
6
29
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAa9C;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAwH3F;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACzB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACxF,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAC5D,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAgvB5F;AAGD,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EAAE,EACrB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,EAAE,WAAW,GAAG,IAAI,EACzB,MAAM,GAAE,MAAM,EAAO,EACrB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,EAC5D,QAAQ,CAAC,EAAE,MAAM,IAAI,GACpB,OAAO,WAAW,EAAE,MAAM,CAG5B"}
|