@jam-comments/server-utilities 4.1.0 → 4.2.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/injectSchema.js +19 -0
- package/dist/cjs/injectSchema.test.js +63 -0
- package/dist/cjs/markupFetcher.js +11 -5
- package/dist/cjs/markupFetcher.test.js +53 -2
- package/dist/cjs/utils.js +42 -1
- package/dist/esm/injectSchema.js +15 -0
- package/dist/esm/injectSchema.test.js +61 -0
- package/dist/esm/markupFetcher.js +12 -6
- package/dist/esm/markupFetcher.test.js +30 -2
- package/dist/esm/utils.js +39 -0
- package/dist/types/injectSchema.d.ts +1 -0
- package/dist/types/injectSchema.test.d.ts +1 -0
- package/dist/types/utils.d.ts +2 -0
- package/package.json +1 -1
|
@@ -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,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.markupFetcher = void 0;
|
|
4
|
+
const injectSchema_1 = require("./injectSchema");
|
|
4
5
|
const utils_1 = require("./utils");
|
|
5
6
|
const markupFetcher = (platform, fetchImplementation = fetch) => {
|
|
6
7
|
return async ({ tz = undefined, path, domain, apiKey, schema, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), }) => {
|
|
@@ -12,10 +13,6 @@ const markupFetcher = (platform, fetchImplementation = fetch) => {
|
|
|
12
13
|
path: path || "/",
|
|
13
14
|
domain,
|
|
14
15
|
});
|
|
15
|
-
if (schema) {
|
|
16
|
-
const preparedSchema = typeof schema !== "string" ? JSON.stringify(schema) : schema;
|
|
17
|
-
params.set("schema", preparedSchema);
|
|
18
|
-
}
|
|
19
16
|
if (trimmedTimezone) {
|
|
20
17
|
params.set("tz", trimmedTimezone);
|
|
21
18
|
}
|
|
@@ -37,7 +34,16 @@ const markupFetcher = (platform, fetchImplementation = fetch) => {
|
|
|
37
34
|
if (!response.ok) {
|
|
38
35
|
throw new Error(`JamComments request failed! Status code: ${response.status}, message: ${response.statusText}, request URL: ${requestUrl}`);
|
|
39
36
|
}
|
|
40
|
-
|
|
37
|
+
const markup = await response.text();
|
|
38
|
+
if (schema) {
|
|
39
|
+
const preparedSchema = typeof schema !== "string" ? JSON.stringify(schema) : schema;
|
|
40
|
+
const parsedSchema = (0, utils_1.parseJson)(preparedSchema);
|
|
41
|
+
if (!parsedSchema) {
|
|
42
|
+
return markup;
|
|
43
|
+
}
|
|
44
|
+
return (0, injectSchema_1.injectSchema)(markup, parsedSchema);
|
|
45
|
+
}
|
|
46
|
+
return markup;
|
|
41
47
|
};
|
|
42
48
|
};
|
|
43
49
|
exports.markupFetcher = markupFetcher;
|
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
26
|
const vitest_1 = require("vitest");
|
|
27
|
+
const injectSchema = __importStar(require("./injectSchema"));
|
|
4
28
|
const markupFetcher_1 = require("./markupFetcher");
|
|
5
29
|
(0, vitest_1.describe)("markupFetcher", () => {
|
|
6
30
|
(0, vitest_1.it)("constructs fetch request correctly", async () => {
|
|
31
|
+
const injectSchemaSpy = vitest_1.vi.spyOn(injectSchema, "injectSchema");
|
|
7
32
|
const fetchMock = vitest_1.vi.fn().mockImplementation(() => {
|
|
8
33
|
return {
|
|
9
34
|
status: 200,
|
|
@@ -18,6 +43,7 @@ const markupFetcher_1 = require("./markupFetcher");
|
|
|
18
43
|
apiKey: "123abc",
|
|
19
44
|
environment: "production",
|
|
20
45
|
});
|
|
46
|
+
(0, vitest_1.expect)(injectSchemaSpy).not.toHaveBeenCalled();
|
|
21
47
|
(0, vitest_1.expect)(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?path=%2Ftest&domain=test.com", vitest_1.expect.objectContaining({
|
|
22
48
|
headers: vitest_1.expect.objectContaining({
|
|
23
49
|
Accept: "application/json",
|
|
@@ -187,6 +213,7 @@ const markupFetcher_1 = require("./markupFetcher");
|
|
|
187
213
|
});
|
|
188
214
|
(0, vitest_1.describe)("passing schema", function () {
|
|
189
215
|
(0, vitest_1.it)("first stringifies schema if given an object", async () => {
|
|
216
|
+
const injectSchemaSpy = vitest_1.vi.spyOn(injectSchema, "injectSchema");
|
|
190
217
|
const fetchMock = vitest_1.vi.fn().mockImplementation(() => {
|
|
191
218
|
return {
|
|
192
219
|
status: 200,
|
|
@@ -202,10 +229,12 @@ const markupFetcher_1 = require("./markupFetcher");
|
|
|
202
229
|
schema: { foo: "bar" },
|
|
203
230
|
environment: "production",
|
|
204
231
|
});
|
|
205
|
-
(0, vitest_1.expect)(
|
|
232
|
+
(0, vitest_1.expect)(injectSchemaSpy).toHaveBeenCalledWith("results!", { foo: "bar" });
|
|
233
|
+
(0, vitest_1.expect)(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?path=%2Ftest&domain=test.com", vitest_1.expect.anything());
|
|
206
234
|
(0, vitest_1.expect)(result).toEqual("results!");
|
|
207
235
|
});
|
|
208
236
|
(0, vitest_1.it)("does not stringify schema if given a string", async () => {
|
|
237
|
+
const injectSchemaSpy = vitest_1.vi.spyOn(injectSchema, "injectSchema");
|
|
209
238
|
const fetchMock = vitest_1.vi.fn().mockImplementation(() => {
|
|
210
239
|
return {
|
|
211
240
|
status: 200,
|
|
@@ -221,7 +250,29 @@ const markupFetcher_1 = require("./markupFetcher");
|
|
|
221
250
|
schema: '{"foo":"bar"}',
|
|
222
251
|
environment: "production",
|
|
223
252
|
});
|
|
224
|
-
(0, vitest_1.expect)(
|
|
253
|
+
(0, vitest_1.expect)(injectSchemaSpy).toHaveBeenCalledWith("results!", { foo: "bar" });
|
|
254
|
+
(0, vitest_1.expect)(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?path=%2Ftest&domain=test.com", vitest_1.expect.anything());
|
|
255
|
+
(0, vitest_1.expect)(result).toEqual("results!");
|
|
256
|
+
});
|
|
257
|
+
(0, vitest_1.it)("returns markup if invalid json is provided", async () => {
|
|
258
|
+
const injectSchemaSpy = vitest_1.vi.spyOn(injectSchema, "injectSchema");
|
|
259
|
+
const fetchMock = vitest_1.vi.fn().mockImplementation(() => {
|
|
260
|
+
return {
|
|
261
|
+
status: 200,
|
|
262
|
+
ok: true,
|
|
263
|
+
text: () => "results!",
|
|
264
|
+
};
|
|
265
|
+
});
|
|
266
|
+
const fetcher = (0, markupFetcher_1.markupFetcher)("test", fetchMock);
|
|
267
|
+
const result = await fetcher({
|
|
268
|
+
path: "/test",
|
|
269
|
+
domain: "test.com",
|
|
270
|
+
apiKey: "123abc",
|
|
271
|
+
schema: "not-valid-json",
|
|
272
|
+
environment: "production",
|
|
273
|
+
});
|
|
274
|
+
(0, vitest_1.expect)(injectSchemaSpy).not.toHaveBeenCalled();
|
|
275
|
+
(0, vitest_1.expect)(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?path=%2Ftest&domain=test.com", vitest_1.expect.anything());
|
|
225
276
|
(0, vitest_1.expect)(result).toEqual("results!");
|
|
226
277
|
});
|
|
227
278
|
});
|
package/dist/cjs/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.reAppendMarkup = exports.getEnvironment = exports.isValidTimezone = void 0;
|
|
3
|
+
exports.unescapeHTML = exports.parseJson = exports.reAppendMarkup = exports.getEnvironment = exports.isValidTimezone = void 0;
|
|
4
4
|
function isValidTimezone(tz) {
|
|
5
5
|
try {
|
|
6
6
|
Intl.DateTimeFormat(undefined, { timeZone: tz });
|
|
@@ -28,3 +28,44 @@ function reAppendMarkup(element, markup) {
|
|
|
28
28
|
element.append(documentFragment);
|
|
29
29
|
}
|
|
30
30
|
exports.reAppendMarkup = reAppendMarkup;
|
|
31
|
+
function parseJson(json) {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(json);
|
|
34
|
+
}
|
|
35
|
+
catch (ex) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.parseJson = parseJson;
|
|
40
|
+
var htmlEntities = {
|
|
41
|
+
nbsp: " ",
|
|
42
|
+
cent: "¢",
|
|
43
|
+
pound: "£",
|
|
44
|
+
yen: "¥",
|
|
45
|
+
euro: "€",
|
|
46
|
+
copy: "©",
|
|
47
|
+
reg: "®",
|
|
48
|
+
lt: "<",
|
|
49
|
+
gt: ">",
|
|
50
|
+
quot: '"',
|
|
51
|
+
amp: "&",
|
|
52
|
+
apos: "'",
|
|
53
|
+
};
|
|
54
|
+
function unescapeHTML(str) {
|
|
55
|
+
return str.replace(/\&([^;]+);/g, function (entity, entityCode) {
|
|
56
|
+
var match;
|
|
57
|
+
if (entityCode in htmlEntities) {
|
|
58
|
+
return htmlEntities[entityCode];
|
|
59
|
+
}
|
|
60
|
+
else if ((match = entityCode.match(/^#x([\da-fA-F]+)$/))) {
|
|
61
|
+
return String.fromCharCode(parseInt(match[1], 16));
|
|
62
|
+
}
|
|
63
|
+
else if ((match = entityCode.match(/^#(\d+)$/))) {
|
|
64
|
+
return String.fromCharCode(~~match[1]);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return entity;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
exports.unescapeHTML = unescapeHTML;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { parseJson, unescapeHTML } from "./utils";
|
|
2
|
+
export function injectSchema(markup, schema) {
|
|
3
|
+
const commentSchema = markup.match(/<div jc-data="jcSchema" data-schema="(.*)"><\/div>/)?.[1];
|
|
4
|
+
if (!commentSchema) {
|
|
5
|
+
return markup;
|
|
6
|
+
}
|
|
7
|
+
const json = parseJson(unescapeHTML(commentSchema));
|
|
8
|
+
if (!json) {
|
|
9
|
+
return markup;
|
|
10
|
+
}
|
|
11
|
+
schema.comment = json;
|
|
12
|
+
return markup
|
|
13
|
+
.replace("<!-- JC:SCHEMA -->", `<script type="application/ld+json">${JSON.stringify(schema)}</script>`)
|
|
14
|
+
.replace(/<div jc-data="jcSchema" data-schema=".*"><\/div>(?:\n+)?/, "");
|
|
15
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { expect, it } from "vitest";
|
|
2
|
+
import { injectSchema } from "./injectSchema";
|
|
3
|
+
it("injects schema into markup", () => {
|
|
4
|
+
const markup = `
|
|
5
|
+
<div id="jcComments">
|
|
6
|
+
<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>
|
|
7
|
+
|
|
8
|
+
<!-- JC:SCHEMA -->
|
|
9
|
+
</div>`;
|
|
10
|
+
const blogPostSchema = {
|
|
11
|
+
"@context": "http://schema.org",
|
|
12
|
+
"@type": "BlogPosting",
|
|
13
|
+
};
|
|
14
|
+
const result = injectSchema(markup, blogPostSchema);
|
|
15
|
+
expect(result).toEqual(`
|
|
16
|
+
<div id="jcComments">
|
|
17
|
+
<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>
|
|
18
|
+
</div>`);
|
|
19
|
+
});
|
|
20
|
+
it("returns markup if schema is not found", () => {
|
|
21
|
+
const markup = `
|
|
22
|
+
<div id="jcComments">
|
|
23
|
+
<!-- JC:SCHEMA -->
|
|
24
|
+
</div>`;
|
|
25
|
+
const blogPostSchema = {
|
|
26
|
+
"@context": "http://schema.org",
|
|
27
|
+
"@type": "BlogPosting",
|
|
28
|
+
};
|
|
29
|
+
const result = injectSchema(markup, blogPostSchema);
|
|
30
|
+
expect(result).toEqual(markup);
|
|
31
|
+
});
|
|
32
|
+
it("returns markup if schema is not valid JSON", () => {
|
|
33
|
+
const markup = `
|
|
34
|
+
<div id="jcComments">
|
|
35
|
+
<div jc-data="jcSchema" data-schema="not-valid-json"></div>
|
|
36
|
+
<!-- JC:SCHEMA -->
|
|
37
|
+
</div>`;
|
|
38
|
+
const blogPostSchema = {
|
|
39
|
+
"@context": "http://schema.org",
|
|
40
|
+
"@type": "BlogPosting",
|
|
41
|
+
};
|
|
42
|
+
const result = injectSchema(markup, blogPostSchema);
|
|
43
|
+
expect(result).toEqual(markup);
|
|
44
|
+
});
|
|
45
|
+
it("injects even when JSON is not HTML-encoded", () => {
|
|
46
|
+
const markup = `
|
|
47
|
+
<div id="jcComments">
|
|
48
|
+
<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>
|
|
49
|
+
|
|
50
|
+
<!-- JC:SCHEMA -->
|
|
51
|
+
</div>`;
|
|
52
|
+
const blogPostSchema = {
|
|
53
|
+
"@context": "http://schema.org",
|
|
54
|
+
"@type": "BlogPosting",
|
|
55
|
+
};
|
|
56
|
+
const result = injectSchema(markup, blogPostSchema);
|
|
57
|
+
expect(result).toEqual(`
|
|
58
|
+
<div id="jcComments">
|
|
59
|
+
<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>
|
|
60
|
+
</div>`);
|
|
61
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { injectSchema } from "./injectSchema";
|
|
2
|
+
import { getEnvironment, isValidTimezone, parseJson } from "./utils";
|
|
2
3
|
export const markupFetcher = (platform, fetchImplementation = fetch) => {
|
|
3
4
|
return async ({ tz = undefined, path, domain, apiKey, schema, baseUrl = "https://go.jamcomments.com", environment = getEnvironment(), }) => {
|
|
4
5
|
const trimmedTimezone = tz?.trim();
|
|
@@ -9,10 +10,6 @@ export const markupFetcher = (platform, fetchImplementation = fetch) => {
|
|
|
9
10
|
path: path || "/",
|
|
10
11
|
domain,
|
|
11
12
|
});
|
|
12
|
-
if (schema) {
|
|
13
|
-
const preparedSchema = typeof schema !== "string" ? JSON.stringify(schema) : schema;
|
|
14
|
-
params.set("schema", preparedSchema);
|
|
15
|
-
}
|
|
16
13
|
if (trimmedTimezone) {
|
|
17
14
|
params.set("tz", trimmedTimezone);
|
|
18
15
|
}
|
|
@@ -34,6 +31,15 @@ export const markupFetcher = (platform, fetchImplementation = fetch) => {
|
|
|
34
31
|
if (!response.ok) {
|
|
35
32
|
throw new Error(`JamComments request failed! Status code: ${response.status}, message: ${response.statusText}, request URL: ${requestUrl}`);
|
|
36
33
|
}
|
|
37
|
-
|
|
34
|
+
const markup = await response.text();
|
|
35
|
+
if (schema) {
|
|
36
|
+
const preparedSchema = typeof schema !== "string" ? JSON.stringify(schema) : schema;
|
|
37
|
+
const parsedSchema = parseJson(preparedSchema);
|
|
38
|
+
if (!parsedSchema) {
|
|
39
|
+
return markup;
|
|
40
|
+
}
|
|
41
|
+
return injectSchema(markup, parsedSchema);
|
|
42
|
+
}
|
|
43
|
+
return markup;
|
|
38
44
|
};
|
|
39
45
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import * as injectSchema from "./injectSchema";
|
|
2
3
|
import { markupFetcher } from "./markupFetcher";
|
|
3
4
|
describe("markupFetcher", () => {
|
|
4
5
|
it("constructs fetch request correctly", async () => {
|
|
6
|
+
const injectSchemaSpy = vi.spyOn(injectSchema, "injectSchema");
|
|
5
7
|
const fetchMock = vi.fn().mockImplementation(() => {
|
|
6
8
|
return {
|
|
7
9
|
status: 200,
|
|
@@ -16,6 +18,7 @@ describe("markupFetcher", () => {
|
|
|
16
18
|
apiKey: "123abc",
|
|
17
19
|
environment: "production",
|
|
18
20
|
});
|
|
21
|
+
expect(injectSchemaSpy).not.toHaveBeenCalled();
|
|
19
22
|
expect(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?path=%2Ftest&domain=test.com", expect.objectContaining({
|
|
20
23
|
headers: expect.objectContaining({
|
|
21
24
|
Accept: "application/json",
|
|
@@ -185,6 +188,7 @@ describe("markupFetcher", () => {
|
|
|
185
188
|
});
|
|
186
189
|
describe("passing schema", function () {
|
|
187
190
|
it("first stringifies schema if given an object", async () => {
|
|
191
|
+
const injectSchemaSpy = vi.spyOn(injectSchema, "injectSchema");
|
|
188
192
|
const fetchMock = vi.fn().mockImplementation(() => {
|
|
189
193
|
return {
|
|
190
194
|
status: 200,
|
|
@@ -200,10 +204,12 @@ describe("passing schema", function () {
|
|
|
200
204
|
schema: { foo: "bar" },
|
|
201
205
|
environment: "production",
|
|
202
206
|
});
|
|
203
|
-
expect(
|
|
207
|
+
expect(injectSchemaSpy).toHaveBeenCalledWith("results!", { foo: "bar" });
|
|
208
|
+
expect(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?path=%2Ftest&domain=test.com", expect.anything());
|
|
204
209
|
expect(result).toEqual("results!");
|
|
205
210
|
});
|
|
206
211
|
it("does not stringify schema if given a string", async () => {
|
|
212
|
+
const injectSchemaSpy = vi.spyOn(injectSchema, "injectSchema");
|
|
207
213
|
const fetchMock = vi.fn().mockImplementation(() => {
|
|
208
214
|
return {
|
|
209
215
|
status: 200,
|
|
@@ -219,7 +225,29 @@ describe("passing schema", function () {
|
|
|
219
225
|
schema: '{"foo":"bar"}',
|
|
220
226
|
environment: "production",
|
|
221
227
|
});
|
|
222
|
-
expect(
|
|
228
|
+
expect(injectSchemaSpy).toHaveBeenCalledWith("results!", { foo: "bar" });
|
|
229
|
+
expect(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?path=%2Ftest&domain=test.com", expect.anything());
|
|
230
|
+
expect(result).toEqual("results!");
|
|
231
|
+
});
|
|
232
|
+
it("returns markup if invalid json is provided", async () => {
|
|
233
|
+
const injectSchemaSpy = vi.spyOn(injectSchema, "injectSchema");
|
|
234
|
+
const fetchMock = vi.fn().mockImplementation(() => {
|
|
235
|
+
return {
|
|
236
|
+
status: 200,
|
|
237
|
+
ok: true,
|
|
238
|
+
text: () => "results!",
|
|
239
|
+
};
|
|
240
|
+
});
|
|
241
|
+
const fetcher = markupFetcher("test", fetchMock);
|
|
242
|
+
const result = await fetcher({
|
|
243
|
+
path: "/test",
|
|
244
|
+
domain: "test.com",
|
|
245
|
+
apiKey: "123abc",
|
|
246
|
+
schema: "not-valid-json",
|
|
247
|
+
environment: "production",
|
|
248
|
+
});
|
|
249
|
+
expect(injectSchemaSpy).not.toHaveBeenCalled();
|
|
250
|
+
expect(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?path=%2Ftest&domain=test.com", expect.anything());
|
|
223
251
|
expect(result).toEqual("results!");
|
|
224
252
|
});
|
|
225
253
|
});
|
package/dist/esm/utils.js
CHANGED
|
@@ -22,3 +22,42 @@ export function reAppendMarkup(element, markup) {
|
|
|
22
22
|
element.innerHTML = "";
|
|
23
23
|
element.append(documentFragment);
|
|
24
24
|
}
|
|
25
|
+
export function parseJson(json) {
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(json);
|
|
28
|
+
}
|
|
29
|
+
catch (ex) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
var htmlEntities = {
|
|
34
|
+
nbsp: " ",
|
|
35
|
+
cent: "¢",
|
|
36
|
+
pound: "£",
|
|
37
|
+
yen: "¥",
|
|
38
|
+
euro: "€",
|
|
39
|
+
copy: "©",
|
|
40
|
+
reg: "®",
|
|
41
|
+
lt: "<",
|
|
42
|
+
gt: ">",
|
|
43
|
+
quot: '"',
|
|
44
|
+
amp: "&",
|
|
45
|
+
apos: "'",
|
|
46
|
+
};
|
|
47
|
+
export function unescapeHTML(str) {
|
|
48
|
+
return str.replace(/\&([^;]+);/g, function (entity, entityCode) {
|
|
49
|
+
var match;
|
|
50
|
+
if (entityCode in htmlEntities) {
|
|
51
|
+
return htmlEntities[entityCode];
|
|
52
|
+
}
|
|
53
|
+
else if ((match = entityCode.match(/^#x([\da-fA-F]+)$/))) {
|
|
54
|
+
return String.fromCharCode(parseInt(match[1], 16));
|
|
55
|
+
}
|
|
56
|
+
else if ((match = entityCode.match(/^#(\d+)$/))) {
|
|
57
|
+
return String.fromCharCode(~~match[1]);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return entity;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function injectSchema(markup: string, schema: Record<string, any>): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export declare function isValidTimezone(tz: string): boolean;
|
|
2
2
|
export declare function getEnvironment(): string;
|
|
3
3
|
export declare function reAppendMarkup(element: HTMLElement, markup: string): void;
|
|
4
|
+
export declare function parseJson(json: string): any;
|
|
5
|
+
export declare function unescapeHTML(str: any): any;
|