@monok/server 1.3.0 → 1.5.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/AGENTS.md +442 -0
- package/README.md +107 -16
- package/dist/affiliate.d.ts +15 -0
- package/dist/affiliate.d.ts.map +1 -0
- package/dist/affiliate.js +96 -0
- package/dist/affiliate.js.map +1 -0
- package/dist/client.d.ts +8 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +38 -6
- package/dist/client.js.map +1 -1
- package/dist/express.d.ts.map +1 -1
- package/dist/express.js +115 -15
- package/dist/express.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +98 -15
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +40 -4
- package/dist/utils.js.map +1 -1
- package/dist-cjs/affiliate.js +96 -0
- package/dist-cjs/affiliate.js.map +1 -0
- package/dist-cjs/client.js +38 -6
- package/dist-cjs/client.js.map +1 -1
- package/dist-cjs/express.js +115 -15
- package/dist-cjs/express.js.map +1 -1
- package/dist-cjs/index.js +1 -0
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/utils.js +40 -4
- package/dist-cjs/utils.js.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const DEFAULT_QUERY_PARAMETER = "monok_ref";
|
|
2
|
+
const DEFAULT_COOKIE_NAME = "monok_ref";
|
|
3
|
+
const MAX_TOKEN_LENGTH = 4096;
|
|
4
|
+
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
5
|
+
const MAX_ATTRIBUTION_WINDOW_DAYS = 365;
|
|
6
|
+
const TOKEN_PATTERN = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
|
|
7
|
+
function validToken(value) {
|
|
8
|
+
return typeof value === "string" &&
|
|
9
|
+
value.length > 0 &&
|
|
10
|
+
value.length <= MAX_TOKEN_LENGTH &&
|
|
11
|
+
TOKEN_PATTERN.test(value);
|
|
12
|
+
}
|
|
13
|
+
function readAttribution(value, nowMs = Date.now()) {
|
|
14
|
+
if (!validToken(value))
|
|
15
|
+
return undefined;
|
|
16
|
+
try {
|
|
17
|
+
const [encodedPayload] = value.split(".");
|
|
18
|
+
const payload = JSON.parse(Buffer.from(encodedPayload, "base64url").toString("utf8"));
|
|
19
|
+
if (payload.version !== 1 ||
|
|
20
|
+
typeof payload.issuedAt !== "number" || !Number.isInteger(payload.issuedAt) ||
|
|
21
|
+
typeof payload.expiresAt !== "number" || !Number.isInteger(payload.expiresAt)) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const lifetimeMs = (payload.expiresAt - payload.issuedAt) * 1000;
|
|
25
|
+
const maxAgeMs = payload.expiresAt * 1000 - nowMs;
|
|
26
|
+
if (lifetimeMs < MILLISECONDS_PER_DAY ||
|
|
27
|
+
lifetimeMs > MAX_ATTRIBUTION_WINDOW_DAYS * MILLISECONDS_PER_DAY ||
|
|
28
|
+
lifetimeMs % MILLISECONDS_PER_DAY !== 0 ||
|
|
29
|
+
payload.issuedAt * 1000 > nowMs + 60000 ||
|
|
30
|
+
maxAgeMs <= 0) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return { token: value, maxAgeMs };
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function readCookie(req, cookieName) {
|
|
40
|
+
const header = req.headers.cookie;
|
|
41
|
+
if (!header)
|
|
42
|
+
return undefined;
|
|
43
|
+
for (const part of header.split(";")) {
|
|
44
|
+
const separator = part.indexOf("=");
|
|
45
|
+
if (separator < 0 || part.slice(0, separator).trim() !== cookieName)
|
|
46
|
+
continue;
|
|
47
|
+
try {
|
|
48
|
+
const value = decodeURIComponent(part.slice(separator + 1).trim());
|
|
49
|
+
return readAttribution(value);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Preserve Monok's signed redirect token in an HttpOnly cookie and expose it as
|
|
59
|
+
* `req.monokAttribution`. This does not expose any content-receiving endpoint.
|
|
60
|
+
*/
|
|
61
|
+
export function monokAffiliateAttribution(options = {}) {
|
|
62
|
+
const queryParameter = options.queryParameter ?? DEFAULT_QUERY_PARAMETER;
|
|
63
|
+
const cookieName = options.cookieName ?? DEFAULT_COOKIE_NAME;
|
|
64
|
+
if (!queryParameter || !cookieName) {
|
|
65
|
+
throw new Error("Affiliate query parameter and cookie name cannot be empty");
|
|
66
|
+
}
|
|
67
|
+
return (req, res, next) => {
|
|
68
|
+
const queryToken = req.query[queryParameter];
|
|
69
|
+
const queryAttribution = readAttribution(queryToken);
|
|
70
|
+
const attribution = queryAttribution
|
|
71
|
+
? queryAttribution
|
|
72
|
+
: readCookie(req, cookieName);
|
|
73
|
+
if (attribution)
|
|
74
|
+
req.monokAttribution = attribution.token;
|
|
75
|
+
if (queryAttribution) {
|
|
76
|
+
res.cookie(cookieName, queryAttribution.token, {
|
|
77
|
+
httpOnly: true,
|
|
78
|
+
secure: options.secure ?? true,
|
|
79
|
+
sameSite: "lax",
|
|
80
|
+
path: "/",
|
|
81
|
+
maxAge: queryAttribution.maxAgeMs,
|
|
82
|
+
...(options.cookieDomain ? { domain: options.cookieDomain } : {})
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (validToken(queryToken)) {
|
|
86
|
+
if (options.cleanUrl ?? true) {
|
|
87
|
+
const cleanUrl = new URL(req.originalUrl, "http://monok.local");
|
|
88
|
+
cleanUrl.searchParams.delete(queryParameter);
|
|
89
|
+
res.redirect(302, cleanUrl.pathname + cleanUrl.search);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
next();
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=affiliate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"affiliate.js","sourceRoot":"","sources":["../src/affiliate.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import type { LinkbackPayload } from "./types.js";
|
|
1
|
+
import type { CreateMonokReferralPayload, LinkbackPayload, MonokAffiliateClientOptions, MonokReferralResult } from "./types.js";
|
|
2
|
+
export declare const DEFAULT_MONOK_BASE_URL = "https://app.monok.com";
|
|
2
3
|
/**
|
|
3
4
|
* Send a linkback to Monok after you publish the article.
|
|
4
5
|
*/
|
|
5
|
-
export declare function sendMonokLinkback({ monokId,
|
|
6
|
+
export declare function sendMonokLinkback({ monokId, externalId, url, title, thumbnailUrl }: LinkbackPayload, opts?: {
|
|
6
7
|
monokBaseUrl?: string;
|
|
7
|
-
userId?: string;
|
|
8
8
|
apiKey?: string;
|
|
9
9
|
}): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Register a newly created merchant customer against a signed attribution token.
|
|
12
|
+
* Repeating the same offer/customer pair is safe and returns the existing referral.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createMonokReferral({ attributionToken, customerReference }: CreateMonokReferralPayload, { apiKey, monokBaseUrl }: MonokAffiliateClientOptions): Promise<MonokReferralResult>;
|
|
10
15
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0BAA0B,EAC1B,eAAe,EACf,2BAA2B,EAC3B,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,sBAAsB,0BAA0B,CAAC;AAE9D;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,eAAe,EAClE,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,EAAE,0BAA0B,EACnE,EAAE,MAAM,EAAE,YAAqC,EAAE,EAAE,2BAA2B,GAC7E,OAAO,CAAC,mBAAmB,CAAC,CAwB9B"}
|
package/dist/client.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import fetch from "node-fetch";
|
|
2
|
+
export const DEFAULT_MONOK_BASE_URL = "https://app.monok.com";
|
|
2
3
|
/**
|
|
3
4
|
* Send a linkback to Monok after you publish the article.
|
|
4
5
|
*/
|
|
5
|
-
export async function sendMonokLinkback({ monokId,
|
|
6
|
-
const endpoint = (opts?.monokBaseUrl ??
|
|
6
|
+
export async function sendMonokLinkback({ monokId, externalId, url, title, thumbnailUrl }, opts) {
|
|
7
|
+
const endpoint = (opts?.monokBaseUrl ?? DEFAULT_MONOK_BASE_URL) + "/api/v1/linkback";
|
|
7
8
|
const payload = {
|
|
8
|
-
puff: { title
|
|
9
|
+
puff: { title },
|
|
9
10
|
id: monokId,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
...(externalId !== undefined && externalId !== null
|
|
12
|
+
? { externalId: String(externalId) }
|
|
13
|
+
: {}),
|
|
14
|
+
url,
|
|
15
|
+
source: new URL(url).hostname,
|
|
13
16
|
...(thumbnailUrl ? { thumbnail: thumbnailUrl } : {})
|
|
14
17
|
};
|
|
15
18
|
const resp = await fetch(endpoint, {
|
|
@@ -25,4 +28,33 @@ export async function sendMonokLinkback({ monokId, publicUrl, title, articleText
|
|
|
25
28
|
throw new Error(`Monok linkback failed: ${resp.status} ${text}`);
|
|
26
29
|
}
|
|
27
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Register a newly created merchant customer against a signed attribution token.
|
|
33
|
+
* Repeating the same offer/customer pair is safe and returns the existing referral.
|
|
34
|
+
*/
|
|
35
|
+
export async function createMonokReferral({ attributionToken, customerReference }, { apiKey, monokBaseUrl = DEFAULT_MONOK_BASE_URL }) {
|
|
36
|
+
if (!apiKey.trim())
|
|
37
|
+
throw new Error("A Monok API key is required");
|
|
38
|
+
if (!attributionToken.trim())
|
|
39
|
+
throw new Error("An attribution token is required");
|
|
40
|
+
if (!customerReference.trim())
|
|
41
|
+
throw new Error("A customer reference is required");
|
|
42
|
+
const endpoint = monokBaseUrl.replace(/\/$/, "") + "/api/v1/affiliate/referrals";
|
|
43
|
+
const resp = await fetch(endpoint, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: {
|
|
46
|
+
"Content-Type": "application/json",
|
|
47
|
+
"X-API-Key": apiKey
|
|
48
|
+
},
|
|
49
|
+
body: JSON.stringify({
|
|
50
|
+
attributionToken,
|
|
51
|
+
customerReference
|
|
52
|
+
})
|
|
53
|
+
});
|
|
54
|
+
if (!resp.ok) {
|
|
55
|
+
const text = await resp.text().catch(() => "");
|
|
56
|
+
throw new Error(`Monok referral registration failed: ${resp.status} ${text}`);
|
|
57
|
+
}
|
|
58
|
+
return await resp.json();
|
|
59
|
+
}
|
|
28
60
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/express.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAwD,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAwD,MAAM,SAAS,CAAC;AAEvF,OAAO,KAAK,EACV,mBAAmB,EAKpB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAmFnE"}
|
package/dist/express.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Router, json } from "express";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
2
3
|
import { assertApiKey, makeThumbSaver } from "./utils.js";
|
|
4
|
+
const PACKAGE_VERSION = readPackageVersion();
|
|
3
5
|
export function createMonokRouter(opts) {
|
|
4
6
|
const r = Router();
|
|
5
7
|
const base = opts.basePath ?? "";
|
|
@@ -7,34 +9,132 @@ export function createMonokRouter(opts) {
|
|
|
7
9
|
r.use(json({ limit: "20mb" }));
|
|
8
10
|
// POST /push
|
|
9
11
|
r.post(base + "/push", wrap(async (req, res) => {
|
|
10
|
-
|
|
12
|
+
assertRequestApiKey(req, opts.apiKey, true);
|
|
11
13
|
const body = req.body;
|
|
12
|
-
if (
|
|
14
|
+
if (body?.id === undefined
|
|
15
|
+
|| body.id === null
|
|
16
|
+
|| (typeof body.id === "string" && body.id.trim() === "")
|
|
17
|
+
|| typeof body.title !== "string"
|
|
18
|
+
|| body.title.trim() === "") {
|
|
13
19
|
return res.status(400).json({ error: "Invalid payload" });
|
|
14
20
|
}
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
const
|
|
21
|
+
// Monok's API integration sends action in the body. Retain query support
|
|
22
|
+
// for older callers and give an explicit query value precedence.
|
|
23
|
+
const action = parseAction(firstQueryValue(req.query.action) ?? body.action);
|
|
24
|
+
const saver = makeThumbSaver(opts.imageDir, opts.maxImageBytes);
|
|
18
25
|
await Promise.resolve(opts.onArticle(body, {
|
|
19
|
-
saveThumbImage: async (fileNameBase) => saver(fileNameBase ?? body.slug ?? body.id, body.thumbImageData),
|
|
26
|
+
saveThumbImage: async (fileNameBase) => saver(fileNameBase ?? body.slug ?? String(body.id), body.thumbImageData),
|
|
20
27
|
action
|
|
21
28
|
}));
|
|
22
|
-
res.json({ ok: true, monokId: body.id });
|
|
29
|
+
res.json({ ok: true, status: "accepted", monokId: body.id });
|
|
23
30
|
}));
|
|
24
31
|
// GET /info
|
|
25
32
|
r.get(base + "/info", wrap(async (req, res) => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
setPrivateNoCacheHeaders(res);
|
|
34
|
+
assertRequestApiKey(req, opts.apiKey);
|
|
35
|
+
const configuredInfo = !opts.getSiteInfo
|
|
36
|
+
? undefined
|
|
37
|
+
: typeof opts.getSiteInfo === "function"
|
|
38
|
+
? await Promise.resolve(opts.getSiteInfo())
|
|
39
|
+
: opts.getSiteInfo;
|
|
40
|
+
const info = configuredInfo
|
|
41
|
+
? { ...configuredInfo, version: PACKAGE_VERSION }
|
|
42
|
+
: defaultSiteInfo();
|
|
34
43
|
res.json(info);
|
|
35
44
|
}));
|
|
45
|
+
// GET /postfilter
|
|
46
|
+
r.get(base + "/postfilter", wrap(async (req, res) => {
|
|
47
|
+
setPrivateNoCacheHeaders(res);
|
|
48
|
+
if (!opts.searchArticles) {
|
|
49
|
+
return res.status(404).json({ error: "Article search not configured" });
|
|
50
|
+
}
|
|
51
|
+
assertRequestApiKey(req, opts.apiKey);
|
|
52
|
+
const amount = parsePositiveInteger(firstQueryValue(req.query.amount), 10, "amount");
|
|
53
|
+
const page = parsePositiveInteger(firstQueryValue(req.query.page), 1, "page");
|
|
54
|
+
const query = {
|
|
55
|
+
postType: firstQueryValue(req.query.post_type)?.trim() || "post",
|
|
56
|
+
amount,
|
|
57
|
+
page,
|
|
58
|
+
...optionalTrimmed("section", firstQueryValue(req.query.section)),
|
|
59
|
+
...optionalTrimmed("tag", firstQueryValue(req.query.tag)),
|
|
60
|
+
...optionalTrimmed("query", firstQueryValue(req.query.q))
|
|
61
|
+
};
|
|
62
|
+
const articles = await Promise.resolve(opts.searchArticles(query));
|
|
63
|
+
if (!Array.isArray(articles)) {
|
|
64
|
+
throw httpError(500, "searchArticles must return an array");
|
|
65
|
+
}
|
|
66
|
+
res.json(articles);
|
|
67
|
+
}));
|
|
36
68
|
return r;
|
|
37
69
|
}
|
|
70
|
+
function assertRequestApiKey(req, expected, allowToken = false) {
|
|
71
|
+
const provided = ((allowToken ? req.header("token") : undefined)
|
|
72
|
+
?? req.header("x-api-key")
|
|
73
|
+
?? firstQueryValue(req.query.apikey));
|
|
74
|
+
assertApiKey(provided, expected);
|
|
75
|
+
}
|
|
76
|
+
function parseAction(value) {
|
|
77
|
+
if (value === undefined || value === null || value === "")
|
|
78
|
+
return undefined;
|
|
79
|
+
if (value === "draft" || value === "publish")
|
|
80
|
+
return value;
|
|
81
|
+
throw httpError(400, "action must be either draft or publish");
|
|
82
|
+
}
|
|
83
|
+
function parsePositiveInteger(value, fallback, name) {
|
|
84
|
+
if (value === undefined || value === "")
|
|
85
|
+
return fallback;
|
|
86
|
+
if (!/^\d+$/.test(value))
|
|
87
|
+
throw httpError(400, `${name} must be a positive integer`);
|
|
88
|
+
const parsed = Number(value);
|
|
89
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1) {
|
|
90
|
+
throw httpError(400, `${name} must be a positive integer`);
|
|
91
|
+
}
|
|
92
|
+
return parsed;
|
|
93
|
+
}
|
|
94
|
+
function firstQueryValue(value) {
|
|
95
|
+
if (typeof value === "string")
|
|
96
|
+
return value;
|
|
97
|
+
if (Array.isArray(value) && typeof value[0] === "string")
|
|
98
|
+
return value[0];
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
function optionalTrimmed(key, value) {
|
|
102
|
+
const trimmed = value?.trim();
|
|
103
|
+
return trimmed ? { [key]: trimmed } : {};
|
|
104
|
+
}
|
|
105
|
+
function setPrivateNoCacheHeaders(res) {
|
|
106
|
+
res.set({
|
|
107
|
+
"Cache-Control": "no-store, no-cache, must-revalidate, max-age=0, private",
|
|
108
|
+
"Pragma": "no-cache",
|
|
109
|
+
"Expires": "0",
|
|
110
|
+
"Surrogate-Control": "no-store",
|
|
111
|
+
"Vary": "Accept-Encoding"
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function defaultSiteInfo() {
|
|
115
|
+
return {
|
|
116
|
+
js_scripts: "Disabled",
|
|
117
|
+
version: PACKAGE_VERSION,
|
|
118
|
+
name: "Custom CMS",
|
|
119
|
+
logo: "",
|
|
120
|
+
categories: [],
|
|
121
|
+
post_types: ["post"],
|
|
122
|
+
tags: [],
|
|
123
|
+
authors: []
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function readPackageVersion() {
|
|
127
|
+
const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
128
|
+
if (typeof packageJson.version !== "string" || packageJson.version.length === 0) {
|
|
129
|
+
throw new Error("@monok/server package version is missing");
|
|
130
|
+
}
|
|
131
|
+
return packageJson.version;
|
|
132
|
+
}
|
|
133
|
+
function httpError(status, message) {
|
|
134
|
+
const error = new Error(message);
|
|
135
|
+
error.status = status;
|
|
136
|
+
return error;
|
|
137
|
+
}
|
|
38
138
|
function wrap(fn) {
|
|
39
139
|
return (req, res, next) => fn(req, res, next).catch((err) => {
|
|
40
140
|
const status = typeof err?.status === "number" ? err.status : 500;
|
package/dist/express.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.js","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAkD,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
export type VFImage = Record<string, unknown>;
|
|
2
|
+
export type MonokArticleId = string | number;
|
|
3
|
+
export type MonokArticleAction = "draft" | "publish";
|
|
4
|
+
export interface MonokArticleAuthor {
|
|
5
|
+
id: string | number;
|
|
6
|
+
name: string;
|
|
7
|
+
}
|
|
8
|
+
export interface MonokArticleCategory {
|
|
9
|
+
name: string;
|
|
10
|
+
weight?: number;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
2
13
|
export interface MonokArticle {
|
|
3
14
|
title: string;
|
|
4
15
|
shortTitle?: string;
|
|
@@ -6,15 +17,21 @@ export interface MonokArticle {
|
|
|
6
17
|
content?: string;
|
|
7
18
|
text?: string;
|
|
8
19
|
slug?: string;
|
|
9
|
-
id:
|
|
20
|
+
id: MonokArticleId;
|
|
21
|
+
action?: MonokArticleAction;
|
|
22
|
+
author?: MonokArticleAuthor;
|
|
23
|
+
categories?: MonokArticleCategory[];
|
|
24
|
+
thumbnail?: string;
|
|
10
25
|
thumbImageData?: string;
|
|
26
|
+
thumbAlt?: string;
|
|
11
27
|
thumbImageDescription?: string;
|
|
12
28
|
language?: string;
|
|
13
|
-
type?:
|
|
29
|
+
type?: string;
|
|
14
30
|
keywords?: string[];
|
|
15
|
-
tags?: string[];
|
|
31
|
+
tags?: string[] | null;
|
|
16
32
|
vfImage?: VFImage;
|
|
17
|
-
sections?: string;
|
|
33
|
+
sections?: string[];
|
|
34
|
+
[key: string]: unknown;
|
|
18
35
|
}
|
|
19
36
|
export interface SiteAuthor {
|
|
20
37
|
name: string;
|
|
@@ -23,26 +40,83 @@ export interface SiteAuthor {
|
|
|
23
40
|
avatar: string;
|
|
24
41
|
roles: string[];
|
|
25
42
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
43
|
+
export interface SiteLanguage {
|
|
44
|
+
id?: string | number;
|
|
45
|
+
name?: string;
|
|
46
|
+
slug?: string;
|
|
47
|
+
locale?: string;
|
|
48
|
+
[key: string]: unknown;
|
|
49
|
+
}
|
|
50
|
+
export type SiteLanguages = SiteLanguage[] | Record<string, SiteLanguage>;
|
|
51
|
+
interface SiteInfoFields {
|
|
30
52
|
js_scripts: "Enabled" | "Disabled";
|
|
31
|
-
version: string;
|
|
32
53
|
name: string;
|
|
33
54
|
logo: string;
|
|
34
55
|
categories: string[];
|
|
35
56
|
post_types: string[];
|
|
36
57
|
tags: string[];
|
|
37
58
|
authors: SiteAuthor[];
|
|
59
|
+
languages?: SiteLanguages;
|
|
60
|
+
[key: string]: unknown;
|
|
61
|
+
}
|
|
62
|
+
/** Site metadata supplied by the host. The router owns the package version. */
|
|
63
|
+
export interface SiteInfoInput extends SiteInfoFields {
|
|
64
|
+
version?: never;
|
|
65
|
+
}
|
|
66
|
+
/** Exact response shape Monok receives from GET /info. */
|
|
67
|
+
export interface SiteInfo extends SiteInfoFields {
|
|
68
|
+
version: string;
|
|
69
|
+
}
|
|
70
|
+
export interface PostFilterQuery {
|
|
71
|
+
postType: string;
|
|
72
|
+
section?: string;
|
|
73
|
+
tag?: string;
|
|
74
|
+
query?: string;
|
|
75
|
+
amount: number;
|
|
76
|
+
page: number;
|
|
77
|
+
}
|
|
78
|
+
/** Exact result shape consumed by Monok's covered-article and link search. */
|
|
79
|
+
export interface PostFilterResult {
|
|
80
|
+
canonical_url: string;
|
|
81
|
+
post_id: string | number;
|
|
82
|
+
title: string | null;
|
|
83
|
+
description: string | null;
|
|
38
84
|
}
|
|
39
85
|
export interface LinkbackPayload {
|
|
40
|
-
monokId:
|
|
41
|
-
|
|
86
|
+
monokId: MonokArticleId;
|
|
87
|
+
externalId?: string | number;
|
|
88
|
+
url: string;
|
|
42
89
|
title: string;
|
|
43
|
-
articleTextSample?: string;
|
|
44
90
|
thumbnailUrl?: string;
|
|
45
91
|
}
|
|
92
|
+
export interface MonokAffiliateAttributionOptions {
|
|
93
|
+
/** Query parameter carrying the signed Monok attribution token. */
|
|
94
|
+
queryParameter?: string;
|
|
95
|
+
/** HttpOnly cookie used to preserve attribution until signup. */
|
|
96
|
+
cookieName?: string;
|
|
97
|
+
/** Optional cookie domain, for example `.example.com`. */
|
|
98
|
+
cookieDomain?: string;
|
|
99
|
+
/** Defaults to true. Set false only for local HTTP development. */
|
|
100
|
+
secure?: boolean;
|
|
101
|
+
/** Remove the token from the address bar with a safe same-site redirect. Defaults to true. */
|
|
102
|
+
cleanUrl?: boolean;
|
|
103
|
+
}
|
|
104
|
+
export interface CreateMonokReferralPayload {
|
|
105
|
+
attributionToken: string;
|
|
106
|
+
/** The merchant's durable, non-sensitive customer ID. */
|
|
107
|
+
customerReference: string;
|
|
108
|
+
}
|
|
109
|
+
export interface MonokAffiliateClientOptions {
|
|
110
|
+
apiKey: string;
|
|
111
|
+
monokBaseUrl?: string;
|
|
112
|
+
}
|
|
113
|
+
export interface MonokReferralResult {
|
|
114
|
+
id: string;
|
|
115
|
+
status: "created" | "existing";
|
|
116
|
+
offerId: string;
|
|
117
|
+
publisherWorkspaceId: string;
|
|
118
|
+
customerReference: string;
|
|
119
|
+
}
|
|
46
120
|
export interface CreateRouterOptions {
|
|
47
121
|
/**
|
|
48
122
|
* Token Monok will send in the `token` header.
|
|
@@ -53,19 +127,28 @@ export interface CreateRouterOptions {
|
|
|
53
127
|
*/
|
|
54
128
|
onArticle: (article: MonokArticle, ctx: {
|
|
55
129
|
saveThumbImage: (fileNameBase?: string) => Promise<string | undefined>;
|
|
56
|
-
action?:
|
|
130
|
+
action?: MonokArticleAction | undefined;
|
|
57
131
|
}) => Promise<void> | void;
|
|
58
132
|
/**
|
|
59
|
-
* Optional. If
|
|
133
|
+
* Optional. If omitted, GET /info returns a minimal Custom CMS fallback.
|
|
134
|
+
*/
|
|
135
|
+
getSiteInfo?: SiteInfoInput | (() => Promise<SiteInfoInput> | SiteInfoInput);
|
|
136
|
+
/**
|
|
137
|
+
* Optional. Enables GET /postfilter for article discovery and search.
|
|
60
138
|
*/
|
|
61
|
-
|
|
139
|
+
searchArticles?: (query: PostFilterQuery) => Promise<PostFilterResult[]> | PostFilterResult[];
|
|
62
140
|
/**
|
|
63
141
|
* Directory where a decoded `thumbImageData` will be saved if present.
|
|
64
142
|
*/
|
|
65
143
|
imageDir?: string;
|
|
144
|
+
/**
|
|
145
|
+
* Maximum decoded JPEG size. Defaults to 15 MiB.
|
|
146
|
+
*/
|
|
147
|
+
maxImageBytes?: number;
|
|
66
148
|
/**
|
|
67
149
|
* Customize route base path (defaults to "").
|
|
68
150
|
*/
|
|
69
151
|
basePath?: string;
|
|
70
152
|
}
|
|
153
|
+
export {};
|
|
71
154
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE9C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare function timingSafeEqual(a: string, b: string): boolean;
|
|
2
2
|
export declare function assertApiKey(headerValue: string | undefined, expected: string): void;
|
|
3
|
-
export declare function makeThumbSaver(imageDir?: string): (base?: string, data?: string) => Promise<string | undefined>;
|
|
3
|
+
export declare function makeThumbSaver(imageDir?: string, maxImageBytes?: number): (base?: string, data?: string) => Promise<string | undefined>;
|
|
4
4
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAMA,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAK7D;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CASpF;AAED,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,aAAa,SAA0B,IACzE,OAAO,MAAM,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA4BzE"}
|