@mikrojs/registry 0.16.0-beta.0 → 0.17.0-next.20260722220623

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Bjørge Næss
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ export { memoryStorage } from './memoryStorage.js';
2
+ export { createRegistry } from './registry.js';
3
+ export type { BuildRecord, DeviceRecord, Registry, RegistryOptions, RegistryStorage, TokenRecord, } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,cAAc,EAAC,MAAM,eAAe,CAAA;AAC5C,YAAY,EACV,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,eAAe,EACf,eAAe,EACf,WAAW,GACZ,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { memoryStorage } from './memoryStorage.js';
2
+ export { createRegistry } from './registry.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAC,cAAc,EAAC,MAAM,eAAe,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { RegistryStorage } from './types.js';
2
+ /** In-memory storage: everything is lost on restart. For tests and demos. */
3
+ export declare function memoryStorage(): RegistryStorage;
4
+ //# sourceMappingURL=memoryStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoryStorage.d.ts","sourceRoot":"","sources":["../src/memoryStorage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4B,eAAe,EAAc,MAAM,YAAY,CAAA;AAEvF,6EAA6E;AAC7E,wBAAgB,aAAa,IAAI,eAAe,CAkD/C"}
@@ -0,0 +1,53 @@
1
+ /** In-memory storage: everything is lost on restart. For tests and demos. */
2
+ export function memoryStorage() {
3
+ const blobs = new Map();
4
+ const builds = new Map();
5
+ const devices = new Map();
6
+ const tokens = new Map();
7
+ return {
8
+ async putBlob(checksum, data) {
9
+ blobs.set(checksum, data);
10
+ },
11
+ async getBlob(checksum) {
12
+ return blobs.get(checksum);
13
+ },
14
+ async getBuild(checksum) {
15
+ return builds.get(checksum);
16
+ },
17
+ async putBuild(record) {
18
+ builds.set(record.checksum, record);
19
+ },
20
+ async listBuilds() {
21
+ return [...builds.values()];
22
+ },
23
+ async getDevice(deviceId) {
24
+ return devices.get(deviceId);
25
+ },
26
+ async getDeviceByCredentialHash(hash) {
27
+ for (const device of devices.values()) {
28
+ if (device.credentialHash === hash)
29
+ return device;
30
+ }
31
+ return undefined;
32
+ },
33
+ async putDevice(record) {
34
+ devices.set(record.deviceId, record);
35
+ },
36
+ async listDevices() {
37
+ return [...devices.values()];
38
+ },
39
+ async getTokenByHash(hash) {
40
+ return tokens.get(hash);
41
+ },
42
+ async putToken(record) {
43
+ tokens.set(record.tokenHash, record);
44
+ },
45
+ async deleteToken(hash) {
46
+ tokens.delete(hash);
47
+ },
48
+ async listTokens() {
49
+ return [...tokens.values()];
50
+ },
51
+ };
52
+ }
53
+ //# sourceMappingURL=memoryStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoryStorage.js","sourceRoot":"","sources":["../src/memoryStorage.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAA;IAC3C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC7C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAA;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAA;IAE7C,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI;YAC1B,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QAC3B,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,QAAQ;YACpB,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC5B,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,QAAQ;YACrB,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC7B,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,MAAM;YACnB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QACrC,CAAC;QACD,KAAK,CAAC,UAAU;YACd,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;QAC7B,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,QAAQ;YACtB,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC9B,CAAC;QACD,KAAK,CAAC,yBAAyB,CAAC,IAAI;YAClC,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBACtC,IAAI,MAAM,CAAC,cAAc,KAAK,IAAI;oBAAE,OAAO,MAAM,CAAA;YACnD,CAAC;YACD,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,MAAM;YACpB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QACtC,CAAC;QACD,KAAK,CAAC,WAAW;YACf,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;QAC9B,CAAC;QACD,KAAK,CAAC,cAAc,CAAC,IAAI;YACvB,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACzB,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,MAAM;YACnB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QACtC,CAAC;QACD,KAAK,CAAC,WAAW,CAAC,IAAI;YACpB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;QACD,KAAK,CAAC,UAAU;YACd,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;QAC7B,CAAC;KACF,CAAA;AACH,CAAC"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { type Server } from 'node:http';
2
+ import type { Registry, RegistryStorage } from './types.js';
3
+ /**
4
+ * File-backed storage: build blobs as `<dir>/builds/<checksum>.tgz`, records
5
+ * in `<dir>/builds.json`, `<dir>/devices.json`, and `<dir>/tokens.json`.
6
+ * Synchronous writes, no locking: one registry process per data dir.
7
+ */
8
+ export declare function fileStorage(dir: string): RegistryStorage;
9
+ /**
10
+ * Serve a registry on node:http. Request bodies are buffered, so
11
+ * `maxBodyBytes` caps them; publish is the only route that needs more than a
12
+ * few kilobytes.
13
+ */
14
+ export declare function serve(registry: Registry, options: {
15
+ port: number;
16
+ hostname?: string;
17
+ maxBodyBytes?: number;
18
+ }): Server;
19
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,MAAM,EAAC,MAAM,WAAW,CAAA;AAGnD,OAAO,KAAK,EAA4B,QAAQ,EAAE,eAAe,EAAc,MAAM,YAAY,CAAA;AAQjG;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAgIxD;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CACnB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAC,GAChE,MAAM,CAiER"}
package/dist/node.js ADDED
@@ -0,0 +1,213 @@
1
+ import { mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from 'node:fs';
2
+ import { createServer } from 'node:http';
3
+ import * as pathlib from 'node:path';
4
+ import { CLIENT_IP_HEADER } from './util.js';
5
+ /** Publish is the only route with a large body; everything else is a small
6
+ * JSON document. Bodies are buffered before routing, so this is what keeps an
7
+ * unauthenticated POST from being an out-of-memory button. */
8
+ const DEFAULT_MAX_BODY_BYTES = 16 * 1024 * 1024;
9
+ /**
10
+ * File-backed storage: build blobs as `<dir>/builds/<checksum>.tgz`, records
11
+ * in `<dir>/builds.json`, `<dir>/devices.json`, and `<dir>/tokens.json`.
12
+ * Synchronous writes, no locking: one registry process per data dir.
13
+ */
14
+ export function fileStorage(dir) {
15
+ const buildsDir = pathlib.join(dir, 'builds');
16
+ mkdirSync(buildsDir, { recursive: true });
17
+ const buildsPath = pathlib.join(dir, 'builds.json');
18
+ const devicesPath = pathlib.join(dir, 'devices.json');
19
+ const tokensPath = pathlib.join(dir, 'tokens.json');
20
+ /** Parsed indexes, keyed by path and invalidated by mtime. Every check-in
21
+ * reads devices.json before it can authenticate the caller, so without this
22
+ * an anonymous request with a junk credential costs a full parse of the
23
+ * fleet, synchronously, on the shared event loop. */
24
+ const cache = new Map();
25
+ function mtimeOf(path) {
26
+ try {
27
+ return statSync(path).mtimeMs;
28
+ }
29
+ catch {
30
+ return undefined;
31
+ }
32
+ }
33
+ /** Keys are untrusted (device ids, token hashes), so the index has no
34
+ * prototype: `constructor` or `__proto__` must be an ordinary miss, not a
35
+ * hit on `Object.prototype` or a write that corrupts it. */
36
+ function readIndex(path) {
37
+ const mtimeMs = mtimeOf(path);
38
+ const cached = cache.get(path);
39
+ if (cached !== undefined && mtimeMs !== undefined && cached.mtimeMs === mtimeMs) {
40
+ return cached.index;
41
+ }
42
+ const index = Object.create(null);
43
+ let parsed;
44
+ try {
45
+ parsed = JSON.parse(readFileSync(path, 'utf-8'));
46
+ }
47
+ catch {
48
+ return index;
49
+ }
50
+ if (typeof parsed !== 'object' || parsed === null)
51
+ return index;
52
+ for (const key of Object.getOwnPropertyNames(parsed)) {
53
+ // defineProperty, not assignment: a `__proto__` key must land as an own
54
+ // property rather than reaching a setter.
55
+ Object.defineProperty(index, key, {
56
+ value: parsed[key],
57
+ writable: true,
58
+ enumerable: true,
59
+ configurable: true,
60
+ });
61
+ }
62
+ if (mtimeMs !== undefined)
63
+ cache.set(path, { mtimeMs, index });
64
+ return index;
65
+ }
66
+ function writeIndex(path, index) {
67
+ // Rewritten in full on every check-in, so a kill or a full disk mid-write
68
+ // must not truncate it: devices.json holds every credential hash, and
69
+ // losing it unenrolls the fleet with no way back but physical access.
70
+ const tmp = `${path}.tmp`;
71
+ try {
72
+ writeFileSync(tmp, JSON.stringify(index, null, 2) + '\n');
73
+ renameSync(tmp, path);
74
+ }
75
+ catch (err) {
76
+ // Callers mutate the cached index in place, so a write that did not land
77
+ // leaves it ahead of the file: drop it rather than serve what is not
78
+ // stored.
79
+ cache.delete(path);
80
+ throw err;
81
+ }
82
+ const mtimeMs = mtimeOf(path);
83
+ if (mtimeMs === undefined)
84
+ cache.delete(path);
85
+ else
86
+ cache.set(path, { mtimeMs, index });
87
+ }
88
+ return {
89
+ async putBlob(checksum, data) {
90
+ writeFileSync(pathlib.join(buildsDir, `${checksum}.tgz`), data);
91
+ },
92
+ async getBlob(checksum) {
93
+ try {
94
+ return new Uint8Array(readFileSync(pathlib.join(buildsDir, `${checksum}.tgz`)));
95
+ }
96
+ catch {
97
+ return undefined;
98
+ }
99
+ },
100
+ async getBuild(checksum) {
101
+ return readIndex(buildsPath)[checksum];
102
+ },
103
+ async putBuild(record) {
104
+ const index = readIndex(buildsPath);
105
+ index[record.checksum] = record;
106
+ writeIndex(buildsPath, index);
107
+ },
108
+ async listBuilds() {
109
+ return Object.values(readIndex(buildsPath));
110
+ },
111
+ async getDevice(deviceId) {
112
+ return readIndex(devicesPath)[deviceId];
113
+ },
114
+ async getDeviceByCredentialHash(hash) {
115
+ return Object.values(readIndex(devicesPath)).find((d) => d.credentialHash === hash);
116
+ },
117
+ async putDevice(record) {
118
+ const index = readIndex(devicesPath);
119
+ index[record.deviceId] = record;
120
+ writeIndex(devicesPath, index);
121
+ },
122
+ async listDevices() {
123
+ return Object.values(readIndex(devicesPath));
124
+ },
125
+ async getTokenByHash(hash) {
126
+ return readIndex(tokensPath)[hash];
127
+ },
128
+ async putToken(record) {
129
+ const index = readIndex(tokensPath);
130
+ index[record.tokenHash] = record;
131
+ writeIndex(tokensPath, index);
132
+ },
133
+ async deleteToken(hash) {
134
+ // Deleted in place rather than rebuilt: `Object.fromEntries` would hand
135
+ // back an index with an ordinary prototype, and these keys are untrusted.
136
+ const index = readIndex(tokensPath);
137
+ Reflect.deleteProperty(index, hash);
138
+ writeIndex(tokensPath, index);
139
+ },
140
+ async listTokens() {
141
+ return Object.values(readIndex(tokensPath));
142
+ },
143
+ };
144
+ }
145
+ /**
146
+ * Serve a registry on node:http. Request bodies are buffered, so
147
+ * `maxBodyBytes` caps them; publish is the only route that needs more than a
148
+ * few kilobytes.
149
+ */
150
+ export function serve(registry, options) {
151
+ const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;
152
+ const server = createServer(async (req, res) => {
153
+ try {
154
+ const chunks = [];
155
+ let received = 0;
156
+ for await (const chunk of req) {
157
+ received += chunk.byteLength;
158
+ // Enforced while reading, before routing or auth: an oversized body
159
+ // must never be held in full, whoever sent it.
160
+ if (received > maxBodyBytes) {
161
+ res.writeHead(413, { 'content-type': 'application/json' });
162
+ res.end(JSON.stringify({ error: 'Request body too large' }));
163
+ req.destroy();
164
+ return;
165
+ }
166
+ chunks.push(chunk);
167
+ }
168
+ const body = Buffer.concat(chunks);
169
+ // Behind a TLS-terminating proxy the socket is plain http, but the
170
+ // origin the registry puts in offer urls has to be the one devices
171
+ // reach: the client rejects a non-https offer url outright.
172
+ const forwardedProto = req.headers['x-forwarded-proto'];
173
+ const proto = (Array.isArray(forwardedProto) ? forwardedProto[0] : forwardedProto)
174
+ ?.split(',')[0]
175
+ ?.trim();
176
+ const scheme = proto === 'https' ? 'https' : 'http';
177
+ const url = `${scheme}://${req.headers.host ?? 'localhost'}${req.url ?? '/'}`;
178
+ // The client's own value for the peer-address header is dropped: it
179
+ // feeds rate limiting, so only the socket may set it.
180
+ const headers = Object.entries(req.headers).flatMap(([name, value]) => name.toLowerCase() === CLIENT_IP_HEADER
181
+ ? []
182
+ : typeof value === 'string'
183
+ ? [[name, value]]
184
+ : (value ?? []).map((v) => [name, v]));
185
+ const remoteAddress = req.socket.remoteAddress;
186
+ if (remoteAddress !== undefined)
187
+ headers.push([CLIENT_IP_HEADER, remoteAddress]);
188
+ const request = new Request(url, {
189
+ method: req.method,
190
+ headers,
191
+ body: body.byteLength > 0 ? body : undefined,
192
+ });
193
+ const response = await registry.fetch(request);
194
+ const responseHeaders = {};
195
+ response.headers.forEach((value, name) => {
196
+ responseHeaders[name] = value;
197
+ });
198
+ res.writeHead(response.status, responseHeaders);
199
+ res.end(Buffer.from(await response.arrayBuffer()));
200
+ }
201
+ catch (err) {
202
+ // The message can name filesystem paths; it belongs in the log, not the
203
+ // response.
204
+ // eslint-disable-next-line no-console
205
+ console.error('registry: request failed', err);
206
+ res.writeHead(500, { 'content-type': 'application/json' });
207
+ res.end(JSON.stringify({ error: 'Internal server error' }));
208
+ }
209
+ });
210
+ server.listen(options.port, options.hostname);
211
+ return server;
212
+ }
213
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Registry, RegistryOptions } from './types.js';
2
+ /**
3
+ * Create a registry as a portable fetch handler. Implements the required
4
+ * contract (publish, build download with Range, enroll + re-mint, browser
5
+ * login) and the advisory reference check-in protocol from
6
+ * docs/registry-spec.md. No orgs, no config sync; the `create` publish field
7
+ * is accepted and ignored (apps are created implicitly on first publish).
8
+ */
9
+ export declare function createRegistry(options: RegistryOptions): Registry;
10
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA4B,QAAQ,EAAE,eAAe,EAAc,MAAM,YAAY,CAAA;AA4GjG;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAylCjE"}