@hatk/hatk 0.0.1-alpha.1 → 0.0.1-alpha.3
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/cli.js +9 -4
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +41 -5
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.js +2 -1
- package/package.json +6 -2
- package/public/robots.txt +2 -0
package/dist/cli.js
CHANGED
|
@@ -797,7 +797,7 @@ RUN npm ci --omit=dev
|
|
|
797
797
|
COPY . .
|
|
798
798
|
RUN node_modules/.bin/hatk build
|
|
799
799
|
EXPOSE 3000
|
|
800
|
-
CMD ["node", "
|
|
800
|
+
CMD ["node", "node_modules/@hatk/hatk/dist/main.js", "config.yaml"]
|
|
801
801
|
`);
|
|
802
802
|
const pkgDeps = { '@hatk/oauth-client': '*', hatk: '*' };
|
|
803
803
|
const pkgDevDeps = {
|
|
@@ -926,6 +926,7 @@ export default defineConfig({
|
|
|
926
926
|
<head>
|
|
927
927
|
<meta charset="utf-8" />
|
|
928
928
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
929
|
+
<meta name="description" content="${name}" />
|
|
929
930
|
<title>${name}</title>
|
|
930
931
|
%sveltekit.head%
|
|
931
932
|
</head>
|
|
@@ -1436,8 +1437,12 @@ else if (command === 'dev') {
|
|
|
1436
1437
|
}
|
|
1437
1438
|
else {
|
|
1438
1439
|
// No frontend — just run the hatk server directly
|
|
1439
|
-
const mainPath = resolve(import.meta.dirname, 'main.
|
|
1440
|
-
execSync(`npx tsx ${mainPath} config.yaml`, {
|
|
1440
|
+
const mainPath = resolve(import.meta.dirname, 'main.js');
|
|
1441
|
+
execSync(`npx tsx ${mainPath} config.yaml`, {
|
|
1442
|
+
stdio: 'inherit',
|
|
1443
|
+
cwd: process.cwd(),
|
|
1444
|
+
env: { ...process.env, DEV_MODE: '1' },
|
|
1445
|
+
});
|
|
1441
1446
|
}
|
|
1442
1447
|
}
|
|
1443
1448
|
catch (e) {
|
|
@@ -1649,7 +1654,7 @@ else if (command === 'schema') {
|
|
|
1649
1654
|
}
|
|
1650
1655
|
else if (command === 'start') {
|
|
1651
1656
|
try {
|
|
1652
|
-
const mainPath = resolve(import.meta.dirname, 'main.
|
|
1657
|
+
const mainPath = resolve(import.meta.dirname, 'main.js');
|
|
1653
1658
|
execSync(`npx tsx ${mainPath} config.yaml`, { stdio: 'inherit', cwd: process.cwd() });
|
|
1654
1659
|
}
|
|
1655
1660
|
catch (e) {
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAA;AAmD3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AA2B9C,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,GAAG,EAAE,eAAe,KAAK;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAC/D,MAAM,CAo8BR"}
|
package/dist/server.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { createServer } from 'node:http';
|
|
2
|
+
import { gzipSync } from 'node:zlib';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
2
4
|
import { readFile } from 'node:fs/promises';
|
|
3
5
|
import { join, extname } from 'node:path';
|
|
4
6
|
import { queryRecords, getRecordByUri, searchRecords, getSchema, reshapeRow, setRepoStatus, getRepoStatus, getRepoRetryInfo, querySQL, insertRecord, deleteRecord, queryLabelsForUris, insertLabels, searchAccounts, listReposPaginated, getCollectionCounts, normalizeValue, getSchemaDump, getPreferences, putPreference, } from "./db.js";
|
|
@@ -39,12 +41,13 @@ function readBodyRaw(req) {
|
|
|
39
41
|
}
|
|
40
42
|
export function startServer(port, collections, publicDir, oauth, admins = [], resolveViewer) {
|
|
41
43
|
const coreXrpc = (method) => `/xrpc/dev.hatk.${method}`;
|
|
44
|
+
const devMode = process.env.DEV_MODE === '1';
|
|
42
45
|
function requireAdmin(viewer, res) {
|
|
43
46
|
if (!viewer) {
|
|
44
47
|
jsonError(res, 401, 'Authentication required');
|
|
45
48
|
return false;
|
|
46
49
|
}
|
|
47
|
-
if (!admins.includes(viewer.did)) {
|
|
50
|
+
if (!devMode && !admins.includes(viewer.did)) {
|
|
48
51
|
jsonError(res, 403, 'Admin access required');
|
|
49
52
|
return false;
|
|
50
53
|
}
|
|
@@ -864,6 +867,21 @@ export function startServer(port, collections, publicDir, oauth, admins = [], re
|
|
|
864
867
|
throw err;
|
|
865
868
|
}
|
|
866
869
|
}
|
|
870
|
+
// GET /robots.txt — serve from user's public dir or fall back to hatk default
|
|
871
|
+
if (url.pathname === '/robots.txt') {
|
|
872
|
+
const userRobots = publicDir ? join(publicDir, 'robots.txt') : null;
|
|
873
|
+
const defaultRobots = join(import.meta.dirname, '../public/robots.txt');
|
|
874
|
+
const robotsPath = userRobots && existsSync(userRobots) ? userRobots : defaultRobots;
|
|
875
|
+
try {
|
|
876
|
+
const content = await readFile(robotsPath);
|
|
877
|
+
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
878
|
+
res.end(content);
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
catch {
|
|
882
|
+
// fall through
|
|
883
|
+
}
|
|
884
|
+
}
|
|
867
885
|
// Static file serving
|
|
868
886
|
if (publicDir) {
|
|
869
887
|
try {
|
|
@@ -912,15 +930,33 @@ export function startServer(port, collections, publicDir, oauth, admins = [], re
|
|
|
912
930
|
server.listen(port, () => log(`[server] ${oauth?.issuer || `http://localhost:${port}`}`));
|
|
913
931
|
return server;
|
|
914
932
|
}
|
|
933
|
+
function sendJson(res, status, body) {
|
|
934
|
+
const acceptEncoding = res.req?.headers['accept-encoding'] || '';
|
|
935
|
+
if (body.length > 1024 && /\bgzip\b/.test(acceptEncoding)) {
|
|
936
|
+
const compressed = gzipSync(body);
|
|
937
|
+
res.writeHead(status, {
|
|
938
|
+
'Content-Type': 'application/json',
|
|
939
|
+
'Content-Encoding': 'gzip',
|
|
940
|
+
Vary: 'Accept-Encoding',
|
|
941
|
+
...(status === 200 ? { 'Cache-Control': 'no-store' } : {}),
|
|
942
|
+
});
|
|
943
|
+
res.end(compressed);
|
|
944
|
+
}
|
|
945
|
+
else {
|
|
946
|
+
res.writeHead(status, {
|
|
947
|
+
'Content-Type': 'application/json',
|
|
948
|
+
...(status === 200 ? { 'Cache-Control': 'no-store' } : {}),
|
|
949
|
+
});
|
|
950
|
+
res.end(body);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
915
953
|
function jsonResponse(res, data) {
|
|
916
|
-
res.
|
|
917
|
-
res.end(JSON.stringify(data, (_, v) => normalizeValue(v)));
|
|
954
|
+
sendJson(res, 200, Buffer.from(JSON.stringify(data, (_, v) => normalizeValue(v))));
|
|
918
955
|
}
|
|
919
956
|
function jsonError(res, status, message) {
|
|
920
957
|
if (res.headersSent)
|
|
921
958
|
return;
|
|
922
|
-
res
|
|
923
|
-
res.end(JSON.stringify({ error: message }));
|
|
959
|
+
sendJson(res, status, Buffer.from(JSON.stringify({ error: message })));
|
|
924
960
|
}
|
|
925
961
|
/** Proxy a request to the user's PDS with DPoP + automatic nonce retry + token refresh. */
|
|
926
962
|
async function proxyToPds(oauthConfig, session, method, pdsUrl, body) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAKlC,wBAAgB,IAAI,CAAC,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAKlC,wBAAgB,IAAI,CAAC,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAuFrD"}
|
package/dist/vite-plugin.js
CHANGED
|
@@ -61,7 +61,7 @@ export function hatk(opts) {
|
|
|
61
61
|
};
|
|
62
62
|
},
|
|
63
63
|
configureServer(server) {
|
|
64
|
-
const mainPath = resolve(import.meta.dirname, 'main.
|
|
64
|
+
const mainPath = resolve(import.meta.dirname, 'main.js');
|
|
65
65
|
const watchDirs = ['xrpc', 'feeds', 'labels', 'jobs', 'setup', 'lexicons'].filter((d) => existsSync(d));
|
|
66
66
|
const watchArgs = watchDirs.flatMap((d) => ['--watch-path', d]);
|
|
67
67
|
serverProcess = spawn('npx', ['tsx', 'watch', ...watchArgs, mainPath, 'config.yaml'], {
|
|
@@ -71,6 +71,7 @@ export function hatk(opts) {
|
|
|
71
71
|
...process.env,
|
|
72
72
|
PORT: String(backendPort),
|
|
73
73
|
OAUTH_ISSUER: process.env.OAUTH_ISSUER || issuer,
|
|
74
|
+
DEV_MODE: '1',
|
|
74
75
|
},
|
|
75
76
|
});
|
|
76
77
|
server.httpServer?.on('close', () => {
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hatk/hatk",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.3",
|
|
4
4
|
"bin": {
|
|
5
5
|
"hatk": "dist/cli.js"
|
|
6
6
|
},
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"fonts",
|
|
10
|
+
"public"
|
|
11
|
+
],
|
|
7
12
|
"type": "module",
|
|
8
13
|
"exports": {
|
|
9
14
|
"./feeds": "./dist/feeds.js",
|
|
@@ -19,7 +24,6 @@
|
|
|
19
24
|
"./test/browser": "./dist/test-browser.js",
|
|
20
25
|
"./vite-plugin": "./dist/vite-plugin.js"
|
|
21
26
|
},
|
|
22
|
-
"files": ["dist", "fonts", "public"],
|
|
23
27
|
"scripts": {
|
|
24
28
|
"build": "tsc -p tsconfig.build.json",
|
|
25
29
|
"prepublishOnly": "npm run build"
|