@jam-comments/server-utilities 4.1.0 → 4.3.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/cjs/index.js +8 -1
- package/dist/cjs/injectSchema.js +19 -0
- package/dist/cjs/injectSchema.test.js +63 -0
- package/dist/cjs/markupFetcher.js +100 -34
- package/dist/cjs/markupFetcher.test.js +272 -26
- package/dist/cjs/utils.js +79 -1
- package/dist/cjs/utils.test.js +43 -0
- package/dist/esm/index.js +4 -2
- package/dist/esm/injectSchema.js +15 -0
- package/dist/esm/injectSchema.test.js +61 -0
- package/dist/esm/markupFetcher.js +96 -34
- package/dist/esm/markupFetcher.test.js +239 -16
- package/dist/esm/utils.js +71 -0
- package/dist/esm/utils.test.js +44 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/injectSchema.d.ts +1 -0
- package/dist/types/injectSchema.test.d.ts +1 -0
- package/dist/types/markupFetcher.d.ts +24 -1
- package/dist/types/utils.d.ts +9 -0
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.logError = exports.log = exports.reAppendMarkup = exports.markupFetcher = void 0;
|
|
6
|
+
exports.logError = exports.log = exports.deleteTempDirectory = exports.reAppendMarkup = exports.fetchAll = exports.markupFetcher = exports.TEMP_DIRECTORY = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
exports.TEMP_DIRECTORY = path_1.default.join(process.cwd(), "_temp_jc");
|
|
4
9
|
var markupFetcher_1 = require("./markupFetcher");
|
|
5
10
|
Object.defineProperty(exports, "markupFetcher", { enumerable: true, get: function () { return markupFetcher_1.markupFetcher; } });
|
|
11
|
+
Object.defineProperty(exports, "fetchAll", { enumerable: true, get: function () { return markupFetcher_1.fetchAll; } });
|
|
6
12
|
var utils_1 = require("./utils");
|
|
7
13
|
Object.defineProperty(exports, "reAppendMarkup", { enumerable: true, get: function () { return utils_1.reAppendMarkup; } });
|
|
14
|
+
Object.defineProperty(exports, "deleteTempDirectory", { enumerable: true, get: function () { return utils_1.deleteTempDirectory; } });
|
|
8
15
|
var log_1 = require("./log");
|
|
9
16
|
Object.defineProperty(exports, "log", { enumerable: true, get: function () { return log_1.log; } });
|
|
10
17
|
Object.defineProperty(exports, "logError", { enumerable: true, get: function () { return log_1.logError; } });
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.injectSchema = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
function injectSchema(markup, schema) {
|
|
6
|
+
const commentSchema = markup.match(/<div jc-data="jcSchema" data-schema="(.*)"><\/div>/)?.[1];
|
|
7
|
+
if (!commentSchema) {
|
|
8
|
+
return markup;
|
|
9
|
+
}
|
|
10
|
+
const json = (0, utils_1.parseJson)((0, utils_1.unescapeHTML)(commentSchema));
|
|
11
|
+
if (!json) {
|
|
12
|
+
return markup;
|
|
13
|
+
}
|
|
14
|
+
schema.comment = json;
|
|
15
|
+
return markup
|
|
16
|
+
.replace("<!-- JC:SCHEMA -->", `<script type="application/ld+json">${JSON.stringify(schema)}</script>`)
|
|
17
|
+
.replace(/<div jc-data="jcSchema" data-schema=".*"><\/div>(?:\n+)?/, "");
|
|
18
|
+
}
|
|
19
|
+
exports.injectSchema = injectSchema;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const injectSchema_1 = require("./injectSchema");
|
|
5
|
+
(0, vitest_1.it)("injects schema into markup", () => {
|
|
6
|
+
const markup = `
|
|
7
|
+
<div id="jcComments">
|
|
8
|
+
<div jc-data="jcSchema" data-schema="[{"@context":"https:\/\/schema.org","@type":"Comment","name":"Alexis","dateCreated":"2022-10-28T10:41:49+00:00","url":"https:\/\/macarthur.me\/posts\/dynamic-routing#comment-133"}]"></div>
|
|
9
|
+
|
|
10
|
+
<!-- JC:SCHEMA -->
|
|
11
|
+
</div>`;
|
|
12
|
+
const blogPostSchema = {
|
|
13
|
+
"@context": "http://schema.org",
|
|
14
|
+
"@type": "BlogPosting",
|
|
15
|
+
};
|
|
16
|
+
const result = (0, injectSchema_1.injectSchema)(markup, blogPostSchema);
|
|
17
|
+
(0, vitest_1.expect)(result).toEqual(`
|
|
18
|
+
<div id="jcComments">
|
|
19
|
+
<script type="application/ld+json">{"@context":"http://schema.org","@type":"BlogPosting","comment":[{"@context":"https://schema.org","@type":"Comment","name":"Alexis","dateCreated":"2022-10-28T10:41:49+00:00","url":"https://macarthur.me/posts/dynamic-routing#comment-133"}]}</script>
|
|
20
|
+
</div>`);
|
|
21
|
+
});
|
|
22
|
+
(0, vitest_1.it)("returns markup if schema is not found", () => {
|
|
23
|
+
const markup = `
|
|
24
|
+
<div id="jcComments">
|
|
25
|
+
<!-- JC:SCHEMA -->
|
|
26
|
+
</div>`;
|
|
27
|
+
const blogPostSchema = {
|
|
28
|
+
"@context": "http://schema.org",
|
|
29
|
+
"@type": "BlogPosting",
|
|
30
|
+
};
|
|
31
|
+
const result = (0, injectSchema_1.injectSchema)(markup, blogPostSchema);
|
|
32
|
+
(0, vitest_1.expect)(result).toEqual(markup);
|
|
33
|
+
});
|
|
34
|
+
(0, vitest_1.it)("returns markup if schema is not valid JSON", () => {
|
|
35
|
+
const markup = `
|
|
36
|
+
<div id="jcComments">
|
|
37
|
+
<div jc-data="jcSchema" data-schema="not-valid-json"></div>
|
|
38
|
+
<!-- JC:SCHEMA -->
|
|
39
|
+
</div>`;
|
|
40
|
+
const blogPostSchema = {
|
|
41
|
+
"@context": "http://schema.org",
|
|
42
|
+
"@type": "BlogPosting",
|
|
43
|
+
};
|
|
44
|
+
const result = (0, injectSchema_1.injectSchema)(markup, blogPostSchema);
|
|
45
|
+
(0, vitest_1.expect)(result).toEqual(markup);
|
|
46
|
+
});
|
|
47
|
+
(0, vitest_1.it)("injects even when JSON is not HTML-encoded", () => {
|
|
48
|
+
const markup = `
|
|
49
|
+
<div id="jcComments">
|
|
50
|
+
<div jc-data="jcSchema" data-schema="[{"@context":"https://schema.org","@type":"Comment","name":"Alexis","dateCreated":"2022-10-28T10:41:49+00:00","url":"https://macarthur.me/posts/dynamic-routing#comment-133"}]"></div>
|
|
51
|
+
|
|
52
|
+
<!-- JC:SCHEMA -->
|
|
53
|
+
</div>`;
|
|
54
|
+
const blogPostSchema = {
|
|
55
|
+
"@context": "http://schema.org",
|
|
56
|
+
"@type": "BlogPosting",
|
|
57
|
+
};
|
|
58
|
+
const result = (0, injectSchema_1.injectSchema)(markup, blogPostSchema);
|
|
59
|
+
(0, vitest_1.expect)(result).toEqual(`
|
|
60
|
+
<div id="jcComments">
|
|
61
|
+
<script type="application/ld+json">{"@context":"http://schema.org","@type":"BlogPosting","comment":[{"@context":"https://schema.org","@type":"Comment","name":"Alexis","dateCreated":"2022-10-28T10:41:49+00:00","url":"https://macarthur.me/posts/dynamic-routing#comment-133"}]}</script>
|
|
62
|
+
</div>`);
|
|
63
|
+
});
|
|
@@ -1,43 +1,109 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.markupFetcher = void 0;
|
|
3
|
+
exports.markupFetcher = exports.makeMarkupRequest = exports.fetchFreshMarkup = exports.batchMarkupFetcher = exports.fetchAll = void 0;
|
|
4
|
+
const injectSchema_1 = require("./injectSchema");
|
|
4
5
|
const utils_1 = require("./utils");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
async function fetchAll({ tz = undefined, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), }, platform, fetchImplementation, batchMarkupFetcherImpl = batchMarkupFetcher) {
|
|
7
|
+
const fetchBatchMarkup = batchMarkupFetcherImpl(platform, fetchImplementation);
|
|
8
|
+
(0, utils_1.createTempDirectory)();
|
|
9
|
+
let shouldKeepFetching = true;
|
|
10
|
+
let page = 1;
|
|
11
|
+
console.log("Fetching comments from JamComments! This might take a sec.");
|
|
12
|
+
try {
|
|
13
|
+
while (shouldKeepFetching) {
|
|
14
|
+
const { data: items, meta: { current_page, last_page }, } = await fetchBatchMarkup({
|
|
15
|
+
domain,
|
|
16
|
+
apiKey,
|
|
17
|
+
baseUrl,
|
|
18
|
+
environment,
|
|
19
|
+
page,
|
|
20
|
+
tz,
|
|
21
|
+
});
|
|
22
|
+
console.log(`Checking for comment data. Batch: ${current_page}/${last_page}`);
|
|
23
|
+
const saveMarkupPromises = items.map((item) => {
|
|
24
|
+
return (0, utils_1.saveFile)(item.path, item.markup);
|
|
25
|
+
});
|
|
26
|
+
await Promise.all(saveMarkupPromises);
|
|
27
|
+
if (current_page === last_page) {
|
|
28
|
+
shouldKeepFetching = false;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
page++;
|
|
32
|
+
}
|
|
10
33
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
(0, utils_1.deleteTempDirectory)();
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.fetchAll = fetchAll;
|
|
41
|
+
function batchMarkupFetcher(platform, fetchImplementation = fetch) {
|
|
42
|
+
return async ({ tz = undefined, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), page = 1, }) => {
|
|
43
|
+
const response = await makeMarkupRequest({ tz, domain, apiKey, baseUrl, environment, page }, "/api/v3/markup/all", fetchImplementation, platform);
|
|
44
|
+
return response.json();
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
exports.batchMarkupFetcher = batchMarkupFetcher;
|
|
48
|
+
async function fetchFreshMarkup({ tz = undefined, path, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), }, fetchImplementation = fetch, platform) {
|
|
49
|
+
const response = await makeMarkupRequest({ tz, path, domain, apiKey, baseUrl, environment }, "/api/v3/markup", fetchImplementation, platform);
|
|
50
|
+
return response.text();
|
|
51
|
+
}
|
|
52
|
+
exports.fetchFreshMarkup = fetchFreshMarkup;
|
|
53
|
+
async function makeMarkupRequest({ tz = undefined, path = undefined, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), page = undefined, }, baseServicePath, fetchImplementation = fetch, platform) {
|
|
54
|
+
const trimmedTimezone = tz?.trim();
|
|
55
|
+
if (trimmedTimezone && !(0, utils_1.isValidTimezone)(trimmedTimezone)) {
|
|
56
|
+
throw new Error(`The timezone passed to JamComments is invalid: ${trimmedTimezone}`);
|
|
57
|
+
}
|
|
58
|
+
const params = new URLSearchParams({
|
|
59
|
+
domain,
|
|
60
|
+
});
|
|
61
|
+
if (path) {
|
|
62
|
+
params.set("path", path);
|
|
63
|
+
}
|
|
64
|
+
if (page) {
|
|
65
|
+
params.set("page", page.toString());
|
|
66
|
+
}
|
|
67
|
+
if (trimmedTimezone) {
|
|
68
|
+
params.set("tz", trimmedTimezone);
|
|
69
|
+
}
|
|
70
|
+
if (environment !== "production") {
|
|
71
|
+
params.set("stub", "true");
|
|
72
|
+
}
|
|
73
|
+
const requestUrl = `${baseUrl}${baseServicePath}?${params}`;
|
|
74
|
+
const response = await fetchImplementation(requestUrl, {
|
|
75
|
+
method: "GET",
|
|
76
|
+
headers: {
|
|
77
|
+
Authorization: `Bearer ${apiKey}`,
|
|
78
|
+
Accept: "application/json",
|
|
79
|
+
"X-Platform": platform,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
if (response.status === 401) {
|
|
83
|
+
throw new Error(`Unauthorized! Are your domain and JamComments API key set correctly?`);
|
|
84
|
+
}
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
throw new Error(`JamComments request failed! Status code: ${response.status}, message: ${response.statusText}, request URL: ${requestUrl}`);
|
|
87
|
+
}
|
|
88
|
+
return response;
|
|
89
|
+
}
|
|
90
|
+
exports.makeMarkupRequest = makeMarkupRequest;
|
|
91
|
+
function markupFetcher(platform, fetchImplementation = fetch) {
|
|
92
|
+
return async ({ tz = undefined, path, domain, apiKey, schema, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), }) => {
|
|
93
|
+
path = path || "/";
|
|
94
|
+
const savedFile = (0, utils_1.readFile)(path);
|
|
95
|
+
const markup = savedFile
|
|
96
|
+
? savedFile
|
|
97
|
+
: await fetchFreshMarkup({ tz, path, domain, apiKey, baseUrl, environment }, fetchImplementation, platform);
|
|
15
98
|
if (schema) {
|
|
16
99
|
const preparedSchema = typeof schema !== "string" ? JSON.stringify(schema) : schema;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (environment !== "production") {
|
|
23
|
-
params.set("stub", "true");
|
|
24
|
-
}
|
|
25
|
-
const requestUrl = `${baseUrl}/api/v3/markup?${params}`;
|
|
26
|
-
const response = await fetchImplementation(requestUrl, {
|
|
27
|
-
method: "GET",
|
|
28
|
-
headers: {
|
|
29
|
-
Authorization: `Bearer ${apiKey}`,
|
|
30
|
-
Accept: "application/json",
|
|
31
|
-
"X-Platform": platform,
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
if (response.status === 401) {
|
|
35
|
-
throw new Error(`Unauthorized! Are your domain and JamComments API key set correctly?`);
|
|
36
|
-
}
|
|
37
|
-
if (!response.ok) {
|
|
38
|
-
throw new Error(`JamComments request failed! Status code: ${response.status}, message: ${response.statusText}, request URL: ${requestUrl}`);
|
|
100
|
+
const parsedSchema = (0, utils_1.parseJson)(preparedSchema);
|
|
101
|
+
if (!parsedSchema) {
|
|
102
|
+
return markup;
|
|
103
|
+
}
|
|
104
|
+
return (0, injectSchema_1.injectSchema)(markup, parsedSchema);
|
|
39
105
|
}
|
|
40
|
-
return
|
|
106
|
+
return markup;
|
|
41
107
|
};
|
|
42
|
-
}
|
|
108
|
+
}
|
|
43
109
|
exports.markupFetcher = markupFetcher;
|