@ryusenkei/maezae 0.5.0 → 0.6.0
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/dev.js +38 -53
- package/dist/types/sdk/src/dev.d.ts +17 -10
- package/package.json +1 -1
package/dist/dev.js
CHANGED
|
@@ -1,71 +1,56 @@
|
|
|
1
1
|
import { i as SIGNED_HEADERS, s as signedHeaders } from "./src-Baj-EC2G.js";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { existsSync,
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { createServer } from "node:http";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
6
|
// src/dev.ts
|
|
7
|
-
/**
|
|
8
|
-
const
|
|
9
|
-
"content-type",
|
|
10
|
-
"etag",
|
|
11
|
-
"x-stale"
|
|
12
|
-
];
|
|
7
|
+
/** 呼び出しの記録のファイル名(メソッド・パス・If-None-Match・本文のハッシュ) */
|
|
8
|
+
const fixtureName = (method, path, ifNoneMatch = "", body = "") => `${createHash("sha256").update(`${method.toUpperCase()} ${path}\n${ifNoneMatch}\n${body}`).digest("hex").slice(0, 16)}.json`;
|
|
13
9
|
/** 記録のディレクトリの URL(末尾はスラッシュ) */
|
|
14
10
|
const dirUrl = (dir) => {
|
|
15
11
|
const url = dir instanceof URL ? dir : pathToFileURL(dir);
|
|
16
12
|
return url.href.endsWith("/") ? url : new URL(`${url.href}/`);
|
|
17
13
|
};
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
/** upstream へ中継(API の鍵を付与、下書きの署名は upstream の URL で改めて付与) */
|
|
21
|
-
async function relay({ origin, apiKey, previewSecret }, path, init) {
|
|
22
|
-
const url = `${origin.replace(/\/$/, "")}${path}`;
|
|
23
|
-
const body = typeof init.body === "string" ? init.body : null;
|
|
24
|
-
const headers = new Headers(init.headers);
|
|
25
|
-
if (previewSecret && headers.has(SIGNED_HEADERS.preview)) headers.set(SIGNED_HEADERS.preview, (await signedHeaders(previewSecret, {
|
|
26
|
-
method: init.method ?? "GET",
|
|
27
|
-
url,
|
|
28
|
-
body
|
|
29
|
-
}, { header: SIGNED_HEADERS.preview })).get(SIGNED_HEADERS.preview));
|
|
30
|
-
headers.set("authorization", `Bearer ${apiKey}`);
|
|
31
|
-
return fetch(url, {
|
|
32
|
-
...init,
|
|
33
|
-
headers
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
/** 記録の配信 API(port Delivery、upstream があれば中継して保存、並行の書き込みは一時のファイルから置き換え) */
|
|
37
|
-
function fixtureDelivery({ dir, upstream }) {
|
|
14
|
+
/** 記録の再生(port Delivery、dir は記録のディレクトリ) */
|
|
15
|
+
function fixtureDelivery(dir) {
|
|
38
16
|
const base = dirUrl(dir);
|
|
39
17
|
return async (path, init = {}) => {
|
|
40
18
|
const method = (init.method ?? "GET").toUpperCase();
|
|
41
|
-
const file =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
19
|
+
const file = new URL(fixtureName(method, path, new Headers(init.headers).get("if-none-match") ?? "", typeof init.body === "string" ? init.body : ""), base);
|
|
20
|
+
if (!existsSync(file)) throw new Error(`配信 API の記録なし: ${method} ${path}(${file.pathname.split("/").at(-1)})`);
|
|
21
|
+
const { status, headers, body } = JSON.parse(readFileSync(file, "utf8"));
|
|
22
|
+
return new Response(status === 304 ? null : body, {
|
|
23
|
+
status,
|
|
24
|
+
headers
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
|
|
29
|
+
/** 公開の配信 API への中継(port Delivery、読み取りだけで書き込みの操作は405) */
|
|
30
|
+
function relayDelivery({ origin, apiKey, previewSecret }) {
|
|
31
|
+
return async (path, init = {}) => {
|
|
32
|
+
const method = (init.method ?? "GET").toUpperCase();
|
|
33
|
+
if (!READ_METHODS.has(method)) return new Response("手元の中継は読み取りだけ", {
|
|
34
|
+
status: 405,
|
|
35
|
+
headers: { allow: "GET, HEAD" }
|
|
36
|
+
});
|
|
37
|
+
const url = `${origin.replace(/\/$/, "")}${path}`;
|
|
38
|
+
const headers = new Headers(init.headers);
|
|
39
|
+
if (previewSecret && headers.has(SIGNED_HEADERS.preview)) headers.set(SIGNED_HEADERS.preview, (await signedHeaders(previewSecret, {
|
|
40
|
+
method,
|
|
41
|
+
url,
|
|
42
|
+
body: null
|
|
43
|
+
}, { header: SIGNED_HEADERS.preview })).get(SIGNED_HEADERS.preview));
|
|
44
|
+
headers.set("authorization", `Bearer ${apiKey}`);
|
|
45
|
+
return fetch(url, {
|
|
46
|
+
...init,
|
|
47
|
+
method,
|
|
48
|
+
headers
|
|
63
49
|
});
|
|
64
50
|
};
|
|
65
51
|
}
|
|
66
|
-
/** 手元の配信 API のサーバー(/content/v1/…
|
|
67
|
-
async function serveDelivery(options) {
|
|
68
|
-
const delivery = fixtureDelivery(options);
|
|
52
|
+
/** 手元の配信 API のサーバー(/content/v1/… だけ、失敗は502、戻り値は origin と停止の関数) */
|
|
53
|
+
async function serveDelivery(delivery, options = {}) {
|
|
69
54
|
const server = createServer(async (req, res) => {
|
|
70
55
|
const chunks = [];
|
|
71
56
|
for await (const chunk of req) chunks.push(chunk);
|
|
@@ -97,4 +82,4 @@ async function serveDelivery(options) {
|
|
|
97
82
|
close: () => new Promise((resolve) => server.close(() => resolve()))
|
|
98
83
|
};
|
|
99
84
|
}
|
|
100
|
-
export { fixtureDelivery, serveDelivery };
|
|
85
|
+
export { fixtureDelivery, fixtureName, relayDelivery, serveDelivery };
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import type { Delivery } from '../../delivery-client/src/index.js';
|
|
2
|
-
/**
|
|
2
|
+
/** 記録の1件(記録のファイルの JSON) */
|
|
3
|
+
export type FixtureResponse = Readonly<{
|
|
4
|
+
method: string;
|
|
5
|
+
path: string;
|
|
6
|
+
status: number;
|
|
7
|
+
headers: Record<string, string>;
|
|
8
|
+
body: string;
|
|
9
|
+
}>;
|
|
10
|
+
/** 呼び出しの記録のファイル名(メソッド・パス・If-None-Match・本文のハッシュ) */
|
|
11
|
+
export declare const fixtureName: (method: string, path: string, ifNoneMatch?: string, body?: string) => string;
|
|
12
|
+
/** 記録の再生(port Delivery、dir は記録のディレクトリ) */
|
|
13
|
+
export declare function fixtureDelivery(dir: string | URL): Delivery;
|
|
14
|
+
/** 公開の配信 API の中継先(origin は媒体の識別子までの URL、例: <公開の配信 API のオリジン>/demo) */
|
|
3
15
|
export type Upstream = Readonly<{
|
|
4
16
|
origin: string;
|
|
5
17
|
apiKey: string;
|
|
6
18
|
previewSecret?: string;
|
|
7
19
|
}>;
|
|
8
|
-
/**
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}>;
|
|
13
|
-
/** 記録の配信 API(port Delivery、upstream があれば中継して保存、並行の書き込みは一時のファイルから置き換え) */
|
|
14
|
-
export declare function fixtureDelivery({ dir, upstream }: FixtureOptions): Delivery;
|
|
15
|
-
/** 手元の配信 API のサーバー(/content/v1/… だけ、記録にない呼び出しは502、戻り値は origin と停止の関数) */
|
|
16
|
-
export declare function serveDelivery(options: FixtureOptions & Readonly<{
|
|
20
|
+
/** 公開の配信 API への中継(port Delivery、読み取りだけで書き込みの操作は405) */
|
|
21
|
+
export declare function relayDelivery({ origin, apiKey, previewSecret }: Upstream): Delivery;
|
|
22
|
+
/** 手元の配信 API のサーバー(/content/v1/… だけ、失敗は502、戻り値は origin と停止の関数) */
|
|
23
|
+
export declare function serveDelivery(delivery: Delivery, options?: Readonly<{
|
|
17
24
|
port?: number;
|
|
18
25
|
hostname?: string;
|
|
19
26
|
}>): Promise<Readonly<{
|