@jam-comments/server-utilities 5.3.0 → 5.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/dist/cjs/index.js CHANGED
@@ -1,17 +1,9 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.logError = exports.log = exports.removeFalseyValues = exports.deleteTempDirectory = 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");
3
+ exports.logError = exports.log = exports.fetchAll = exports.markupFetcher = void 0;
9
4
  var markupFetcher_1 = require("./markupFetcher");
10
5
  Object.defineProperty(exports, "markupFetcher", { enumerable: true, get: function () { return markupFetcher_1.markupFetcher; } });
11
6
  Object.defineProperty(exports, "fetchAll", { enumerable: true, get: function () { return markupFetcher_1.fetchAll; } });
12
- var utils_1 = require("./utils");
13
- Object.defineProperty(exports, "deleteTempDirectory", { enumerable: true, get: function () { return utils_1.deleteTempDirectory; } });
14
- Object.defineProperty(exports, "removeFalseyValues", { enumerable: true, get: function () { return utils_1.removeFalseyValues; } });
15
7
  var log_1 = require("./log");
16
8
  Object.defineProperty(exports, "log", { enumerable: true, get: function () { return log_1.log; } });
17
9
  Object.defineProperty(exports, "logError", { enumerable: true, get: function () { return log_1.logError; } });
@@ -1,4 +1,27 @@
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
  exports.fetchAll = fetchAll;
4
27
  exports.batchMarkupFetcher = batchMarkupFetcher;
@@ -7,9 +30,11 @@ exports.makeMarkupRequest = makeMarkupRequest;
7
30
  exports.markupFetcher = markupFetcher;
8
31
  const injectSchema_1 = require("./injectSchema");
9
32
  const utils_1 = require("./utils");
10
- async function fetchAll({ tz = undefined, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), copy = {}, }, platform, fetchImplementation = fetch, batchMarkupFetcherImpl = batchMarkupFetcher) {
33
+ const BASE_URL = "https://go.jamcomments.com";
34
+ async function fetchAll({ tz = undefined, dateFormat = undefined, domain, apiKey, baseUrl = BASE_URL, environment = (0, utils_1.getEnvironment)(), copy = {}, }, platform, fetchImplementation = fetch, batchMarkupFetcherImpl = batchMarkupFetcher) {
35
+ const { createTempDirectory, deleteTempDirectory, saveFile } = await Promise.resolve().then(() => __importStar(require("./nodeUtils")));
11
36
  const fetchBatchMarkup = batchMarkupFetcherImpl(platform, fetchImplementation);
12
- (0, utils_1.createTempDirectory)();
37
+ await createTempDirectory();
13
38
  let shouldKeepFetching = true;
14
39
  let page = 1;
15
40
  console.log("Fetching comments from JamComments! This might take a sec.");
@@ -22,11 +47,12 @@ async function fetchAll({ tz = undefined, domain, apiKey, baseUrl = "https://go.
22
47
  environment,
23
48
  page,
24
49
  tz,
50
+ dateFormat,
25
51
  copy,
26
52
  });
27
53
  console.log(`Checking for comment data. Batch: ${current_page}/${last_page}`);
28
54
  const saveMarkupPromises = items.map((item) => {
29
- return (0, utils_1.saveFile)(item.path, item.markup);
55
+ return saveFile(item.path, item.markup);
30
56
  });
31
57
  await Promise.all(saveMarkupPromises);
32
58
  if (current_page === last_page) {
@@ -38,21 +64,21 @@ async function fetchAll({ tz = undefined, domain, apiKey, baseUrl = "https://go.
38
64
  }
39
65
  }
40
66
  catch (error) {
41
- (0, utils_1.deleteTempDirectory)();
67
+ await deleteTempDirectory();
42
68
  throw error;
43
69
  }
44
70
  }
45
71
  function batchMarkupFetcher(platform, fetchImplementation = fetch) {
46
- return async ({ tz = undefined, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), page = 1, copy = {}, }) => {
47
- const response = await makeMarkupRequest({ tz, domain, apiKey, baseUrl, environment, page, copy }, "/api/v3/markup/all", fetchImplementation, platform);
72
+ return async ({ tz, copy, domain, apiKey, dateFormat, baseUrl = BASE_URL, environment = (0, utils_1.getEnvironment)(), page = 1, }) => {
73
+ const response = await makeMarkupRequest({ tz, domain, apiKey, baseUrl, environment, page, copy, dateFormat }, "/api/v3/markup/all", fetchImplementation, platform);
48
74
  return response.json();
49
75
  };
50
76
  }
51
- async function fetchFreshMarkup({ tz = undefined, path, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), copy = {}, }, fetchImplementation = fetch, platform) {
52
- const response = await makeMarkupRequest({ tz, path, domain, apiKey, baseUrl, environment, copy }, "/api/v3/markup", fetchImplementation, platform);
77
+ async function fetchFreshMarkup({ tz, path, copy, domain, apiKey, dateFormat, baseUrl = BASE_URL, environment = (0, utils_1.getEnvironment)(), }, fetchImplementation = fetch, platform) {
78
+ const response = await makeMarkupRequest({ tz, path, domain, apiKey, baseUrl, environment, copy, dateFormat }, "/api/v3/markup", fetchImplementation, platform);
53
79
  return response.text();
54
80
  }
55
- async function makeMarkupRequest({ tz = undefined, path = undefined, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), page = undefined, copy = {}, }, baseServicePath, fetchImplementation = fetch, platform) {
81
+ async function makeMarkupRequest({ tz, path, page, domain, apiKey, dateFormat, copy = {}, baseUrl = BASE_URL, environment = (0, utils_1.getEnvironment)(), }, baseServicePath, fetchImplementation = fetch, platform) {
56
82
  const trimmedTimezone = tz?.trim();
57
83
  if (trimmedTimezone && !(0, utils_1.isValidTimezone)(trimmedTimezone)) {
58
84
  throw new Error(`The timezone passed to JamComments is invalid: ${trimmedTimezone}`);
@@ -69,6 +95,9 @@ async function makeMarkupRequest({ tz = undefined, path = undefined, domain, api
69
95
  if (trimmedTimezone) {
70
96
  params.set("tz", trimmedTimezone);
71
97
  }
98
+ if (dateFormat) {
99
+ params.set("date_format", dateFormat);
100
+ }
72
101
  if (environment !== "production") {
73
102
  params.set("stub", "true");
74
103
  }
@@ -93,17 +122,21 @@ async function makeMarkupRequest({ tz = undefined, path = undefined, domain, api
93
122
  return response;
94
123
  }
95
124
  function markupFetcher(platform, fetchImplementation = fetch) {
96
- return async ({ tz = undefined, path, domain, apiKey, schema, baseUrl = "https://go.jamcomments.com", environment = (0, utils_1.getEnvironment)(), copy = {}, }) => {
125
+ return async ({ tz = undefined, path, domain, apiKey, schema, dateFormat, baseUrl = BASE_URL, environment = (0, utils_1.getEnvironment)(), copy = {}, }) => {
97
126
  path = path || "/";
98
- const savedFile = (() => {
99
- if (!(0, utils_1.tempDirectoryExists)()) {
127
+ const savedFile = await (async () => {
128
+ if (typeof process === "undefined") {
129
+ return null;
130
+ }
131
+ const { tempDirectoryExists, readFile, getEmptyMarkup } = await Promise.resolve().then(() => __importStar(require("./nodeUtils")));
132
+ if (!(await tempDirectoryExists())) {
100
133
  return null;
101
134
  }
102
- return (0, utils_1.readFile)(path) || (0, utils_1.getEmptyMarkup)();
135
+ return (await readFile(path)) || getEmptyMarkup();
103
136
  })();
104
137
  const markup = savedFile
105
138
  ? savedFile
106
- : await fetchFreshMarkup({ tz, path, domain, apiKey, baseUrl, environment, copy }, fetchImplementation, platform);
139
+ : await fetchFreshMarkup({ tz, path, domain, apiKey, baseUrl, environment, copy, dateFormat }, fetchImplementation, platform);
107
140
  if (schema) {
108
141
  const preparedSchema = typeof schema !== "string" ? JSON.stringify(schema) : schema;
109
142
  const parsedSchema = (0, utils_1.parseJson)(preparedSchema);
@@ -27,7 +27,7 @@ const vitest_1 = require("vitest");
27
27
  const injectSchema = __importStar(require("./injectSchema"));
28
28
  const fetcherExports = __importStar(require("./markupFetcher"));
29
29
  const node_test_1 = require("node:test");
30
- const utilsExports = __importStar(require("./utils"));
30
+ const utilsExports = __importStar(require("./nodeUtils"));
31
31
  const { deleteTempDirectory } = utilsExports;
32
32
  const { markupFetcher, batchMarkupFetcher } = fetcherExports;
33
33
  (0, vitest_1.beforeEach)(() => {
@@ -67,6 +67,8 @@ const { markupFetcher, batchMarkupFetcher } = fetcherExports;
67
67
  domain: "test.com",
68
68
  apiKey: "123abc",
69
69
  baseUrl: "https://go.jamcomments.com",
70
+ copy: {},
71
+ dateFormat: undefined,
70
72
  environment: "production",
71
73
  page: 1,
72
74
  tz: undefined,
@@ -120,6 +122,8 @@ const { markupFetcher, batchMarkupFetcher } = fetcherExports;
120
122
  domain: "test.com",
121
123
  apiKey: "123abc",
122
124
  baseUrl: "https://go.jamcomments.com",
125
+ copy: {},
126
+ dateFormat: undefined,
123
127
  environment: "production",
124
128
  page: 1,
125
129
  tz: undefined,
@@ -129,6 +133,8 @@ const { markupFetcher, batchMarkupFetcher } = fetcherExports;
129
133
  domain: "test.com",
130
134
  apiKey: "123abc",
131
135
  baseUrl: "https://go.jamcomments.com",
136
+ copy: {},
137
+ dateFormat: undefined,
132
138
  environment: "production",
133
139
  page: 2,
134
140
  tz: undefined,
@@ -157,7 +163,7 @@ const { markupFetcher, batchMarkupFetcher } = fetcherExports;
157
163
  }
158
164
  (0, vitest_1.expect)(deleteTempDirectorySpy).toHaveBeenCalledOnce();
159
165
  });
160
- vitest_1.it.only("handles copy overrides", async () => {
166
+ (0, vitest_1.it)("handles copy overrides", async () => {
161
167
  const saveFileSpy = vitest_1.vi.spyOn(utilsExports, "saveFile");
162
168
  const mockBatchFetcher = vitest_1.vi.fn().mockReturnValue({
163
169
  data: [
@@ -201,6 +207,42 @@ const { markupFetcher, batchMarkupFetcher } = fetcherExports;
201
207
  });
202
208
  (0, vitest_1.expect)(saveFileSpy).toHaveBeenCalledTimes(2);
203
209
  });
210
+ (0, vitest_1.it)("allows you to pass a custom date format", async () => {
211
+ const mockBatchFetcher = vitest_1.vi.fn().mockReturnValue({
212
+ data: [
213
+ { path: "/test", markup: "markup1" },
214
+ { path: "/test2", markup: "markup2" },
215
+ ],
216
+ meta: {
217
+ current_page: 1,
218
+ from: 1,
219
+ last_page: 1,
220
+ path: "/test",
221
+ per_page: 10,
222
+ to: 2,
223
+ total: 2,
224
+ },
225
+ });
226
+ const batchMarkupFetcherMock = vitest_1.vi.fn().mockImplementation((a, b) => {
227
+ return mockBatchFetcher;
228
+ });
229
+ await fetcherExports.fetchAll({
230
+ domain: "test.com",
231
+ apiKey: "123abc",
232
+ environment: "production",
233
+ dateFormat: "yyyy-MM-dd",
234
+ }, "test_platform", vitest_1.vi.fn(), batchMarkupFetcherMock);
235
+ (0, vitest_1.expect)(mockBatchFetcher).toHaveBeenCalledWith({
236
+ domain: "test.com",
237
+ apiKey: "123abc",
238
+ baseUrl: "https://go.jamcomments.com",
239
+ copy: {},
240
+ dateFormat: "yyyy-MM-dd",
241
+ environment: "production",
242
+ page: 1,
243
+ tz: undefined,
244
+ });
245
+ });
204
246
  });
205
247
  (0, vitest_1.describe)("batchMarkupFetcher", () => {
206
248
  (0, vitest_1.it)("constructs fetch request correctly", async () => {
@@ -419,6 +461,24 @@ const { markupFetcher, batchMarkupFetcher } = fetcherExports;
419
461
  (0, vitest_1.expect)(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?domain=test.com&path=%2F&copy_confirmation_message=custom+confirmation+message&copy_submit_button=custom+submit+button", vitest_1.expect.anything());
420
462
  (0, vitest_1.expect)(result).toEqual("results!");
421
463
  });
464
+ (0, vitest_1.it)("passes date format string", async () => {
465
+ const fetchMock = vitest_1.vi.fn().mockImplementation(() => {
466
+ return {
467
+ status: 200,
468
+ ok: true,
469
+ text: () => "results!",
470
+ };
471
+ });
472
+ const fetcher = markupFetcher("test", fetchMock);
473
+ await fetcher({
474
+ path: null,
475
+ domain: "test.com",
476
+ apiKey: "123abc",
477
+ environment: "production",
478
+ dateFormat: "yyyy-MM-dd",
479
+ });
480
+ (0, vitest_1.expect)(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?domain=test.com&path=%2F&date_format=yyyy-MM-dd", vitest_1.expect.anything());
481
+ });
422
482
  (0, vitest_1.it)("response isn't ok", async () => {
423
483
  const fetchMock = vitest_1.vi.fn().mockImplementation(() => {
424
484
  return {
@@ -438,7 +498,7 @@ const { markupFetcher, batchMarkupFetcher } = fetcherExports;
438
498
  (0, vitest_1.it)("makes fresh request when temp directory does not exist", async () => {
439
499
  const tempDirectoryExistsSpy = vitest_1.vi
440
500
  .spyOn(utilsExports, "tempDirectoryExists")
441
- .mockReturnValue(false);
501
+ .mockReturnValue(Promise.resolve(false));
442
502
  const readFileSpy = vitest_1.vi.spyOn(utilsExports, "readFile");
443
503
  const fetchMock = vitest_1.vi.fn().mockImplementation(() => {
444
504
  return {
@@ -462,10 +522,10 @@ const { markupFetcher, batchMarkupFetcher } = fetcherExports;
462
522
  (0, vitest_1.it)("uses saved markup when it exists", async () => {
463
523
  const tempDirectoryExistsSpy = vitest_1.vi
464
524
  .spyOn(utilsExports, "tempDirectoryExists")
465
- .mockReturnValue(true);
525
+ .mockReturnValue(Promise.resolve(true));
466
526
  const readFileSpy = vitest_1.vi
467
527
  .spyOn(utilsExports, "readFile")
468
- .mockReturnValue("saved markup");
528
+ .mockReturnValue(Promise.resolve("saved markup"));
469
529
  const fetchMock = vitest_1.vi.fn();
470
530
  const fetcher = markupFetcher("test", fetchMock);
471
531
  const result = await fetcher({
@@ -482,13 +542,13 @@ const { markupFetcher, batchMarkupFetcher } = fetcherExports;
482
542
  (0, vitest_1.it)("uses the EMPTY template when there's no saved file for a post", async () => {
483
543
  const tempDirectoryExistsSpy = vitest_1.vi
484
544
  .spyOn(utilsExports, "tempDirectoryExists")
485
- .mockReturnValue(true);
545
+ .mockReturnValue(Promise.resolve(true));
486
546
  const readFileSpy = vitest_1.vi
487
547
  .spyOn(utilsExports, "readFile")
488
548
  .mockReturnValue(null);
489
549
  const getEmptyMarkupSpy = vitest_1.vi
490
550
  .spyOn(utilsExports, "getEmptyMarkup")
491
- .mockReturnValue("<!-- EMPTY -->");
551
+ .mockReturnValue(Promise.resolve("<!-- EMPTY -->"));
492
552
  const fetchMock = vitest_1.vi.fn();
493
553
  const fetcher = markupFetcher("test", fetchMock);
494
554
  const result = await fetcher({
@@ -0,0 +1,74 @@
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
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.getTempDirectory = getTempDirectory;
27
+ exports.deleteTempDirectory = deleteTempDirectory;
28
+ exports.createTempDirectory = createTempDirectory;
29
+ exports.readFile = readFile;
30
+ exports.getEmptyMarkup = getEmptyMarkup;
31
+ exports.tempDirectoryExists = tempDirectoryExists;
32
+ exports.saveFile = saveFile;
33
+ const fs_1 = require("fs");
34
+ const utils_1 = require("./utils");
35
+ async function getTempDirectory() {
36
+ const path = await Promise.resolve().then(() => __importStar(require("path")));
37
+ return path.join(process.cwd(), "_temp_jc");
38
+ }
39
+ async function deleteTempDirectory() {
40
+ const tempDirectory = await getTempDirectory();
41
+ if ((0, fs_1.existsSync)(tempDirectory)) {
42
+ (0, fs_1.rmdirSync)(tempDirectory, { recursive: true });
43
+ }
44
+ }
45
+ async function createTempDirectory(mkdirSyncImpl = fs_1.mkdirSync, existsSyncImpl = fs_1.existsSync) {
46
+ const tempDirectory = await getTempDirectory();
47
+ if (!(await tempDirectoryExists(existsSyncImpl))) {
48
+ mkdirSyncImpl(tempDirectory);
49
+ }
50
+ }
51
+ async function readFile(name, readFileSyncImpl = fs_1.readFileSync) {
52
+ const fileName = (0, utils_1.toSavedFileName)(name);
53
+ try {
54
+ return readFileSyncImpl(`${await getTempDirectory()}/${fileName}`, "utf8");
55
+ }
56
+ catch (error) {
57
+ return null;
58
+ }
59
+ }
60
+ function getEmptyMarkup() {
61
+ return readFile("EMPTY");
62
+ }
63
+ async function tempDirectoryExists(existsSyncImpl = fs_1.existsSync) {
64
+ return existsSyncImpl(await getTempDirectory());
65
+ }
66
+ async function saveFile(name, data, writeFileImpl = fs_1.writeFile) {
67
+ const fileName = (0, utils_1.toSavedFileName)(name);
68
+ const tempDirectory = await getTempDirectory();
69
+ return new Promise(async (resolve) => {
70
+ writeFileImpl(`${tempDirectory}/${fileName}`, data, () => {
71
+ resolve();
72
+ });
73
+ });
74
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const nodeUtils_1 = require("./nodeUtils");
5
+ (0, vitest_1.describe)("createTempDirectory()", () => {
6
+ (0, vitest_1.it)("creates temp directory fresh", async () => {
7
+ const tempDirectory = await (0, nodeUtils_1.getTempDirectory)();
8
+ const mkdirSyncMock = vitest_1.vi.fn();
9
+ const existsSyncMock = vitest_1.vi.fn().mockReturnValue(false);
10
+ await new Promise((resolve) => {
11
+ (0, vitest_1.expect)(async () => {
12
+ await (0, nodeUtils_1.createTempDirectory)(mkdirSyncMock, existsSyncMock);
13
+ resolve();
14
+ }).not.toThrow();
15
+ });
16
+ (0, vitest_1.expect)(mkdirSyncMock).toHaveBeenCalledWith(tempDirectory);
17
+ });
18
+ (0, vitest_1.it)("does not throw error when it already exists", () => {
19
+ const mkdirSyncMock = vitest_1.vi.fn().mockImplementation(() => {
20
+ throw new Error("Directory already exists");
21
+ });
22
+ const existsSyncMock = vitest_1.vi.fn().mockReturnValue(true);
23
+ (0, vitest_1.expect)(() => (0, nodeUtils_1.createTempDirectory)(mkdirSyncMock, existsSyncMock)).not.toThrow();
24
+ (0, vitest_1.expect)(mkdirSyncMock).not.toHaveBeenCalledWith();
25
+ });
26
+ });
27
+ (0, vitest_1.describe)("readFile()", () => {
28
+ (0, vitest_1.it)("reads the file", async () => {
29
+ const readFileSyncMock = vitest_1.vi.fn().mockReturnValue("file contents");
30
+ const tempDirectory = await (0, nodeUtils_1.getTempDirectory)();
31
+ (0, vitest_1.expect)(await (0, nodeUtils_1.readFile)("hey/there", readFileSyncMock)).toEqual("file contents");
32
+ (0, vitest_1.expect)(readFileSyncMock).toHaveBeenCalledWith(`${tempDirectory}/hey::there`, "utf8");
33
+ });
34
+ (0, vitest_1.it)("returns null when file doesn't exist", async () => {
35
+ const readFileSyncMock = vitest_1.vi.fn().mockImplementation(() => {
36
+ throw new Error("File not found");
37
+ });
38
+ (0, vitest_1.expect)(await (0, nodeUtils_1.readFile)("hey/there", readFileSyncMock)).toEqual(null);
39
+ });
40
+ });
41
+ (0, vitest_1.describe)("saveFile()", () => {
42
+ (0, vitest_1.it)("saves the file", async () => {
43
+ const writeFileMock = vitest_1.vi.fn().mockImplementation((file, data, cb) => cb());
44
+ const tempDirectory = await (0, nodeUtils_1.getTempDirectory)();
45
+ await (0, nodeUtils_1.saveFile)("hey/there", "file contents", writeFileMock);
46
+ (0, vitest_1.expect)(writeFileMock).toHaveBeenCalledWith(`${tempDirectory}/hey::there`, "file contents", vitest_1.expect.any(Function));
47
+ });
48
+ });
package/dist/cjs/utils.js CHANGED
@@ -4,16 +4,8 @@ exports.isValidTimezone = isValidTimezone;
4
4
  exports.getEnvironment = getEnvironment;
5
5
  exports.parseJson = parseJson;
6
6
  exports.unescapeHTML = unescapeHTML;
7
- exports.deleteTempDirectory = deleteTempDirectory;
8
- exports.createTempDirectory = createTempDirectory;
9
7
  exports.toSavedFileName = toSavedFileName;
10
- exports.readFile = readFile;
11
- exports.getEmptyMarkup = getEmptyMarkup;
12
- exports.tempDirectoryExists = tempDirectoryExists;
13
- exports.saveFile = saveFile;
14
8
  exports.removeFalseyValues = removeFalseyValues;
15
- const fs_1 = require("fs");
16
- const _1 = require(".");
17
9
  function isValidTimezone(tz) {
18
10
  try {
19
11
  Intl.DateTimeFormat(undefined, { timeZone: tz });
@@ -70,42 +62,9 @@ function unescapeHTML(str) {
70
62
  }
71
63
  });
72
64
  }
73
- function deleteTempDirectory() {
74
- if ((0, fs_1.existsSync)(_1.TEMP_DIRECTORY)) {
75
- (0, fs_1.rmdirSync)(_1.TEMP_DIRECTORY, { recursive: true });
76
- }
77
- }
78
- function createTempDirectory(mkdirSyncImpl = fs_1.mkdirSync, existsSyncImpl = fs_1.existsSync) {
79
- if (!tempDirectoryExists(existsSyncImpl)) {
80
- mkdirSyncImpl(_1.TEMP_DIRECTORY);
81
- }
82
- }
83
65
  function toSavedFileName(name) {
84
66
  return name.replace(/^\//, "").replace(/\//g, "::");
85
67
  }
86
- function readFile(name, readFileSyncImpl = fs_1.readFileSync) {
87
- const fileName = toSavedFileName(name);
88
- try {
89
- return readFileSyncImpl(`${_1.TEMP_DIRECTORY}/${fileName}`, "utf8");
90
- }
91
- catch (error) {
92
- return null;
93
- }
94
- }
95
- function getEmptyMarkup() {
96
- return readFile("EMPTY");
97
- }
98
- function tempDirectoryExists(existsSyncImpl = fs_1.existsSync) {
99
- return existsSyncImpl(_1.TEMP_DIRECTORY);
100
- }
101
- function saveFile(name, data, writeFileImpl = fs_1.writeFile) {
102
- const fileName = toSavedFileName(name);
103
- return new Promise((resolve) => {
104
- writeFileImpl(`${_1.TEMP_DIRECTORY}/${fileName}`, data, () => {
105
- resolve();
106
- });
107
- });
108
- }
109
68
  function removeFalseyValues(obj) {
110
69
  const filteredItems = Object.entries(obj).filter(([, value]) => value);
111
70
  return Object.fromEntries(filteredItems);
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const vitest_1 = require("vitest");
4
4
  const utils_1 = require("./utils");
5
- const _1 = require(".");
6
5
  const env = process.env;
7
6
  (0, vitest_1.beforeEach)(() => {
8
7
  vitest_1.vi.resetModules();
@@ -45,48 +44,11 @@ const env = process.env;
45
44
  });
46
45
  });
47
46
  });
48
- (0, vitest_1.describe)("createTempDirectory()", () => {
49
- (0, vitest_1.it)("creates temp directory fresh", () => {
50
- const mkdirSyncMock = vitest_1.vi.fn();
51
- const existsSyncMock = vitest_1.vi.fn().mockReturnValue(false);
52
- (0, vitest_1.expect)(() => (0, utils_1.createTempDirectory)(mkdirSyncMock, existsSyncMock)).not.toThrow();
53
- (0, vitest_1.expect)(mkdirSyncMock).toHaveBeenCalledWith(_1.TEMP_DIRECTORY);
54
- });
55
- (0, vitest_1.it)("does not throw error when it already exists", () => {
56
- const mkdirSyncMock = vitest_1.vi.fn().mockImplementation(() => {
57
- throw new Error("Directory already exists");
58
- });
59
- const existsSyncMock = vitest_1.vi.fn().mockReturnValue(true);
60
- (0, vitest_1.expect)(() => (0, utils_1.createTempDirectory)(mkdirSyncMock, existsSyncMock)).not.toThrow();
61
- (0, vitest_1.expect)(mkdirSyncMock).not.toHaveBeenCalledWith();
62
- });
63
- });
64
47
  (0, vitest_1.describe)("toSavedFileName()", () => {
65
48
  (0, vitest_1.it)("replaces slashes with double colons", () => {
66
49
  (0, vitest_1.expect)((0, utils_1.toSavedFileName)("/hey/there")).toEqual("hey::there");
67
50
  });
68
51
  });
69
- (0, vitest_1.describe)("readFile()", () => {
70
- (0, vitest_1.it)("reads the file", () => {
71
- const readFileSyncMock = vitest_1.vi.fn().mockReturnValue("file contents");
72
- (0, vitest_1.expect)((0, utils_1.readFile)("hey/there", readFileSyncMock)).toEqual("file contents");
73
- (0, vitest_1.expect)(readFileSyncMock).toHaveBeenCalledWith(`${_1.TEMP_DIRECTORY}/hey::there`, "utf8");
74
- });
75
- (0, vitest_1.it)("returns null when file doesn't exist", () => {
76
- const readFileSyncMock = vitest_1.vi.fn().mockImplementation(() => {
77
- throw new Error("File not found");
78
- });
79
- (0, vitest_1.expect)((0, utils_1.readFile)("hey/there", readFileSyncMock)).toEqual(null);
80
- });
81
- });
82
- (0, vitest_1.describe)("saveFile()", () => {
83
- (0, vitest_1.it)("saves the file", async () => {
84
- const writeFileMock = vitest_1.vi.fn();
85
- const result = (0, utils_1.saveFile)("hey/there", "file contents", writeFileMock);
86
- (0, vitest_1.expect)(writeFileMock).toHaveBeenCalledWith(`${_1.TEMP_DIRECTORY}/hey::there`, "file contents", vitest_1.expect.any(Function));
87
- (0, vitest_1.expect)(result).toBeInstanceOf(Promise);
88
- });
89
- });
90
52
  (0, vitest_1.describe)("removeFalseyValues()", () => {
91
53
  (0, vitest_1.it)("should remove falsey values", () => {
92
54
  (0, vitest_1.expect)((0, utils_1.removeFalseyValues)({ a: 1, b: 0, d: null, e: "" })).toEqual({
package/dist/esm/index.js CHANGED
@@ -1,5 +1,2 @@
1
- import path from "path";
2
- export const TEMP_DIRECTORY = path.join(process.cwd(), "_temp_jc");
3
1
  export { markupFetcher, fetchAll } from "./markupFetcher";
4
- export { deleteTempDirectory, removeFalseyValues } from "./utils";
5
2
  export { log, logError } from "./log";
@@ -1,8 +1,10 @@
1
1
  import { injectSchema } from "./injectSchema";
2
- import { createTempDirectory, deleteTempDirectory, getEmptyMarkup, getEnvironment, isValidTimezone, parseJson, readFile, saveFile, tempDirectoryExists, } from "./utils";
3
- export async function fetchAll({ tz = undefined, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = getEnvironment(), copy = {}, }, platform, fetchImplementation = fetch, batchMarkupFetcherImpl = batchMarkupFetcher) {
2
+ import { getEnvironment, isValidTimezone, parseJson } from "./utils";
3
+ const BASE_URL = "https://go.jamcomments.com";
4
+ export async function fetchAll({ tz = undefined, dateFormat = undefined, domain, apiKey, baseUrl = BASE_URL, environment = getEnvironment(), copy = {}, }, platform, fetchImplementation = fetch, batchMarkupFetcherImpl = batchMarkupFetcher) {
5
+ const { createTempDirectory, deleteTempDirectory, saveFile } = await import("./nodeUtils");
4
6
  const fetchBatchMarkup = batchMarkupFetcherImpl(platform, fetchImplementation);
5
- createTempDirectory();
7
+ await createTempDirectory();
6
8
  let shouldKeepFetching = true;
7
9
  let page = 1;
8
10
  console.log("Fetching comments from JamComments! This might take a sec.");
@@ -15,6 +17,7 @@ export async function fetchAll({ tz = undefined, domain, apiKey, baseUrl = "http
15
17
  environment,
16
18
  page,
17
19
  tz,
20
+ dateFormat,
18
21
  copy,
19
22
  });
20
23
  console.log(`Checking for comment data. Batch: ${current_page}/${last_page}`);
@@ -31,21 +34,21 @@ export async function fetchAll({ tz = undefined, domain, apiKey, baseUrl = "http
31
34
  }
32
35
  }
33
36
  catch (error) {
34
- deleteTempDirectory();
37
+ await deleteTempDirectory();
35
38
  throw error;
36
39
  }
37
40
  }
38
41
  export function batchMarkupFetcher(platform, fetchImplementation = fetch) {
39
- return async ({ tz = undefined, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = getEnvironment(), page = 1, copy = {}, }) => {
40
- const response = await makeMarkupRequest({ tz, domain, apiKey, baseUrl, environment, page, copy }, "/api/v3/markup/all", fetchImplementation, platform);
42
+ return async ({ tz, copy, domain, apiKey, dateFormat, baseUrl = BASE_URL, environment = getEnvironment(), page = 1, }) => {
43
+ const response = await makeMarkupRequest({ tz, domain, apiKey, baseUrl, environment, page, copy, dateFormat }, "/api/v3/markup/all", fetchImplementation, platform);
41
44
  return response.json();
42
45
  };
43
46
  }
44
- export async function fetchFreshMarkup({ tz = undefined, path, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = getEnvironment(), copy = {}, }, fetchImplementation = fetch, platform) {
45
- const response = await makeMarkupRequest({ tz, path, domain, apiKey, baseUrl, environment, copy }, "/api/v3/markup", fetchImplementation, platform);
47
+ export async function fetchFreshMarkup({ tz, path, copy, domain, apiKey, dateFormat, baseUrl = BASE_URL, environment = getEnvironment(), }, fetchImplementation = fetch, platform) {
48
+ const response = await makeMarkupRequest({ tz, path, domain, apiKey, baseUrl, environment, copy, dateFormat }, "/api/v3/markup", fetchImplementation, platform);
46
49
  return response.text();
47
50
  }
48
- export async function makeMarkupRequest({ tz = undefined, path = undefined, domain, apiKey, baseUrl = "https://go.jamcomments.com", environment = getEnvironment(), page = undefined, copy = {}, }, baseServicePath, fetchImplementation = fetch, platform) {
51
+ export async function makeMarkupRequest({ tz, path, page, domain, apiKey, dateFormat, copy = {}, baseUrl = BASE_URL, environment = getEnvironment(), }, baseServicePath, fetchImplementation = fetch, platform) {
49
52
  const trimmedTimezone = tz?.trim();
50
53
  if (trimmedTimezone && !isValidTimezone(trimmedTimezone)) {
51
54
  throw new Error(`The timezone passed to JamComments is invalid: ${trimmedTimezone}`);
@@ -62,6 +65,9 @@ export async function makeMarkupRequest({ tz = undefined, path = undefined, doma
62
65
  if (trimmedTimezone) {
63
66
  params.set("tz", trimmedTimezone);
64
67
  }
68
+ if (dateFormat) {
69
+ params.set("date_format", dateFormat);
70
+ }
65
71
  if (environment !== "production") {
66
72
  params.set("stub", "true");
67
73
  }
@@ -86,17 +92,21 @@ export async function makeMarkupRequest({ tz = undefined, path = undefined, doma
86
92
  return response;
87
93
  }
88
94
  export function markupFetcher(platform, fetchImplementation = fetch) {
89
- return async ({ tz = undefined, path, domain, apiKey, schema, baseUrl = "https://go.jamcomments.com", environment = getEnvironment(), copy = {}, }) => {
95
+ return async ({ tz = undefined, path, domain, apiKey, schema, dateFormat, baseUrl = BASE_URL, environment = getEnvironment(), copy = {}, }) => {
90
96
  path = path || "/";
91
- const savedFile = (() => {
92
- if (!tempDirectoryExists()) {
97
+ const savedFile = await (async () => {
98
+ if (typeof process === "undefined") {
99
+ return null;
100
+ }
101
+ const { tempDirectoryExists, readFile, getEmptyMarkup } = await import("./nodeUtils");
102
+ if (!(await tempDirectoryExists())) {
93
103
  return null;
94
104
  }
95
- return readFile(path) || getEmptyMarkup();
105
+ return (await readFile(path)) || getEmptyMarkup();
96
106
  })();
97
107
  const markup = savedFile
98
108
  ? savedFile
99
- : await fetchFreshMarkup({ tz, path, domain, apiKey, baseUrl, environment, copy }, fetchImplementation, platform);
109
+ : await fetchFreshMarkup({ tz, path, domain, apiKey, baseUrl, environment, copy, dateFormat }, fetchImplementation, platform);
100
110
  if (schema) {
101
111
  const preparedSchema = typeof schema !== "string" ? JSON.stringify(schema) : schema;
102
112
  const parsedSchema = parseJson(preparedSchema);
@@ -2,7 +2,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
2
2
  import * as injectSchema from "./injectSchema";
3
3
  import * as fetcherExports from "./markupFetcher";
4
4
  import { afterEach } from "node:test";
5
- import * as utilsExports from "./utils";
5
+ import * as utilsExports from "./nodeUtils";
6
6
  const { deleteTempDirectory } = utilsExports;
7
7
  const { markupFetcher, batchMarkupFetcher } = fetcherExports;
8
8
  beforeEach(() => {
@@ -42,6 +42,8 @@ describe("fetchAll()", () => {
42
42
  domain: "test.com",
43
43
  apiKey: "123abc",
44
44
  baseUrl: "https://go.jamcomments.com",
45
+ copy: {},
46
+ dateFormat: undefined,
45
47
  environment: "production",
46
48
  page: 1,
47
49
  tz: undefined,
@@ -95,6 +97,8 @@ describe("fetchAll()", () => {
95
97
  domain: "test.com",
96
98
  apiKey: "123abc",
97
99
  baseUrl: "https://go.jamcomments.com",
100
+ copy: {},
101
+ dateFormat: undefined,
98
102
  environment: "production",
99
103
  page: 1,
100
104
  tz: undefined,
@@ -104,6 +108,8 @@ describe("fetchAll()", () => {
104
108
  domain: "test.com",
105
109
  apiKey: "123abc",
106
110
  baseUrl: "https://go.jamcomments.com",
111
+ copy: {},
112
+ dateFormat: undefined,
107
113
  environment: "production",
108
114
  page: 2,
109
115
  tz: undefined,
@@ -132,7 +138,7 @@ describe("fetchAll()", () => {
132
138
  }
133
139
  expect(deleteTempDirectorySpy).toHaveBeenCalledOnce();
134
140
  });
135
- it.only("handles copy overrides", async () => {
141
+ it("handles copy overrides", async () => {
136
142
  const saveFileSpy = vi.spyOn(utilsExports, "saveFile");
137
143
  const mockBatchFetcher = vi.fn().mockReturnValue({
138
144
  data: [
@@ -176,6 +182,42 @@ describe("fetchAll()", () => {
176
182
  });
177
183
  expect(saveFileSpy).toHaveBeenCalledTimes(2);
178
184
  });
185
+ it("allows you to pass a custom date format", async () => {
186
+ const mockBatchFetcher = vi.fn().mockReturnValue({
187
+ data: [
188
+ { path: "/test", markup: "markup1" },
189
+ { path: "/test2", markup: "markup2" },
190
+ ],
191
+ meta: {
192
+ current_page: 1,
193
+ from: 1,
194
+ last_page: 1,
195
+ path: "/test",
196
+ per_page: 10,
197
+ to: 2,
198
+ total: 2,
199
+ },
200
+ });
201
+ const batchMarkupFetcherMock = vi.fn().mockImplementation((a, b) => {
202
+ return mockBatchFetcher;
203
+ });
204
+ await fetcherExports.fetchAll({
205
+ domain: "test.com",
206
+ apiKey: "123abc",
207
+ environment: "production",
208
+ dateFormat: "yyyy-MM-dd",
209
+ }, "test_platform", vi.fn(), batchMarkupFetcherMock);
210
+ expect(mockBatchFetcher).toHaveBeenCalledWith({
211
+ domain: "test.com",
212
+ apiKey: "123abc",
213
+ baseUrl: "https://go.jamcomments.com",
214
+ copy: {},
215
+ dateFormat: "yyyy-MM-dd",
216
+ environment: "production",
217
+ page: 1,
218
+ tz: undefined,
219
+ });
220
+ });
179
221
  });
180
222
  describe("batchMarkupFetcher", () => {
181
223
  it("constructs fetch request correctly", async () => {
@@ -394,6 +436,24 @@ describe("markupFetcher", () => {
394
436
  expect(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?domain=test.com&path=%2F&copy_confirmation_message=custom+confirmation+message&copy_submit_button=custom+submit+button", expect.anything());
395
437
  expect(result).toEqual("results!");
396
438
  });
439
+ it("passes date format string", async () => {
440
+ const fetchMock = vi.fn().mockImplementation(() => {
441
+ return {
442
+ status: 200,
443
+ ok: true,
444
+ text: () => "results!",
445
+ };
446
+ });
447
+ const fetcher = markupFetcher("test", fetchMock);
448
+ await fetcher({
449
+ path: null,
450
+ domain: "test.com",
451
+ apiKey: "123abc",
452
+ environment: "production",
453
+ dateFormat: "yyyy-MM-dd",
454
+ });
455
+ expect(fetchMock).toHaveBeenCalledWith("https://go.jamcomments.com/api/v3/markup?domain=test.com&path=%2F&date_format=yyyy-MM-dd", expect.anything());
456
+ });
397
457
  it("response isn't ok", async () => {
398
458
  const fetchMock = vi.fn().mockImplementation(() => {
399
459
  return {
@@ -413,7 +473,7 @@ describe("markupFetcher", () => {
413
473
  it("makes fresh request when temp directory does not exist", async () => {
414
474
  const tempDirectoryExistsSpy = vi
415
475
  .spyOn(utilsExports, "tempDirectoryExists")
416
- .mockReturnValue(false);
476
+ .mockReturnValue(Promise.resolve(false));
417
477
  const readFileSpy = vi.spyOn(utilsExports, "readFile");
418
478
  const fetchMock = vi.fn().mockImplementation(() => {
419
479
  return {
@@ -437,10 +497,10 @@ describe("markupFetcher", () => {
437
497
  it("uses saved markup when it exists", async () => {
438
498
  const tempDirectoryExistsSpy = vi
439
499
  .spyOn(utilsExports, "tempDirectoryExists")
440
- .mockReturnValue(true);
500
+ .mockReturnValue(Promise.resolve(true));
441
501
  const readFileSpy = vi
442
502
  .spyOn(utilsExports, "readFile")
443
- .mockReturnValue("saved markup");
503
+ .mockReturnValue(Promise.resolve("saved markup"));
444
504
  const fetchMock = vi.fn();
445
505
  const fetcher = markupFetcher("test", fetchMock);
446
506
  const result = await fetcher({
@@ -457,13 +517,13 @@ describe("markupFetcher", () => {
457
517
  it("uses the EMPTY template when there's no saved file for a post", async () => {
458
518
  const tempDirectoryExistsSpy = vi
459
519
  .spyOn(utilsExports, "tempDirectoryExists")
460
- .mockReturnValue(true);
520
+ .mockReturnValue(Promise.resolve(true));
461
521
  const readFileSpy = vi
462
522
  .spyOn(utilsExports, "readFile")
463
523
  .mockReturnValue(null);
464
524
  const getEmptyMarkupSpy = vi
465
525
  .spyOn(utilsExports, "getEmptyMarkup")
466
- .mockReturnValue("<!-- EMPTY -->");
526
+ .mockReturnValue(Promise.resolve("<!-- EMPTY -->"));
467
527
  const fetchMock = vi.fn();
468
528
  const fetcher = markupFetcher("test", fetchMock);
469
529
  const result = await fetcher({
@@ -0,0 +1,42 @@
1
+ import { existsSync, mkdirSync, readFileSync, rmdirSync, writeFile } from "fs";
2
+ import { toSavedFileName } from "./utils";
3
+ export async function getTempDirectory() {
4
+ const path = await import("path");
5
+ return path.join(process.cwd(), "_temp_jc");
6
+ }
7
+ export async function deleteTempDirectory() {
8
+ const tempDirectory = await getTempDirectory();
9
+ if (existsSync(tempDirectory)) {
10
+ rmdirSync(tempDirectory, { recursive: true });
11
+ }
12
+ }
13
+ export async function createTempDirectory(mkdirSyncImpl = mkdirSync, existsSyncImpl = existsSync) {
14
+ const tempDirectory = await getTempDirectory();
15
+ if (!(await tempDirectoryExists(existsSyncImpl))) {
16
+ mkdirSyncImpl(tempDirectory);
17
+ }
18
+ }
19
+ export async function readFile(name, readFileSyncImpl = readFileSync) {
20
+ const fileName = toSavedFileName(name);
21
+ try {
22
+ return readFileSyncImpl(`${await getTempDirectory()}/${fileName}`, "utf8");
23
+ }
24
+ catch (error) {
25
+ return null;
26
+ }
27
+ }
28
+ export function getEmptyMarkup() {
29
+ return readFile("EMPTY");
30
+ }
31
+ export async function tempDirectoryExists(existsSyncImpl = existsSync) {
32
+ return existsSyncImpl(await getTempDirectory());
33
+ }
34
+ export async function saveFile(name, data, writeFileImpl = writeFile) {
35
+ const fileName = toSavedFileName(name);
36
+ const tempDirectory = await getTempDirectory();
37
+ return new Promise(async (resolve) => {
38
+ writeFileImpl(`${tempDirectory}/${fileName}`, data, () => {
39
+ resolve();
40
+ });
41
+ });
42
+ }
@@ -0,0 +1,46 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { createTempDirectory, getTempDirectory, readFile, saveFile, } from "./nodeUtils";
3
+ describe("createTempDirectory()", () => {
4
+ it("creates temp directory fresh", async () => {
5
+ const tempDirectory = await getTempDirectory();
6
+ const mkdirSyncMock = vi.fn();
7
+ const existsSyncMock = vi.fn().mockReturnValue(false);
8
+ await new Promise((resolve) => {
9
+ expect(async () => {
10
+ await createTempDirectory(mkdirSyncMock, existsSyncMock);
11
+ resolve();
12
+ }).not.toThrow();
13
+ });
14
+ expect(mkdirSyncMock).toHaveBeenCalledWith(tempDirectory);
15
+ });
16
+ it("does not throw error when it already exists", () => {
17
+ const mkdirSyncMock = vi.fn().mockImplementation(() => {
18
+ throw new Error("Directory already exists");
19
+ });
20
+ const existsSyncMock = vi.fn().mockReturnValue(true);
21
+ expect(() => createTempDirectory(mkdirSyncMock, existsSyncMock)).not.toThrow();
22
+ expect(mkdirSyncMock).not.toHaveBeenCalledWith();
23
+ });
24
+ });
25
+ describe("readFile()", () => {
26
+ it("reads the file", async () => {
27
+ const readFileSyncMock = vi.fn().mockReturnValue("file contents");
28
+ const tempDirectory = await getTempDirectory();
29
+ expect(await readFile("hey/there", readFileSyncMock)).toEqual("file contents");
30
+ expect(readFileSyncMock).toHaveBeenCalledWith(`${tempDirectory}/hey::there`, "utf8");
31
+ });
32
+ it("returns null when file doesn't exist", async () => {
33
+ const readFileSyncMock = vi.fn().mockImplementation(() => {
34
+ throw new Error("File not found");
35
+ });
36
+ expect(await readFile("hey/there", readFileSyncMock)).toEqual(null);
37
+ });
38
+ });
39
+ describe("saveFile()", () => {
40
+ it("saves the file", async () => {
41
+ const writeFileMock = vi.fn().mockImplementation((file, data, cb) => cb());
42
+ const tempDirectory = await getTempDirectory();
43
+ await saveFile("hey/there", "file contents", writeFileMock);
44
+ expect(writeFileMock).toHaveBeenCalledWith(`${tempDirectory}/hey::there`, "file contents", expect.any(Function));
45
+ });
46
+ });
package/dist/esm/utils.js CHANGED
@@ -1,5 +1,3 @@
1
- import { existsSync, mkdirSync, readFileSync, rmdirSync, writeFile } from "fs";
2
- import { TEMP_DIRECTORY } from ".";
3
1
  export function isValidTimezone(tz) {
4
2
  try {
5
3
  Intl.DateTimeFormat(undefined, { timeZone: tz });
@@ -56,42 +54,9 @@ export function unescapeHTML(str) {
56
54
  }
57
55
  });
58
56
  }
59
- export function deleteTempDirectory() {
60
- if (existsSync(TEMP_DIRECTORY)) {
61
- rmdirSync(TEMP_DIRECTORY, { recursive: true });
62
- }
63
- }
64
- export function createTempDirectory(mkdirSyncImpl = mkdirSync, existsSyncImpl = existsSync) {
65
- if (!tempDirectoryExists(existsSyncImpl)) {
66
- mkdirSyncImpl(TEMP_DIRECTORY);
67
- }
68
- }
69
57
  export function toSavedFileName(name) {
70
58
  return name.replace(/^\//, "").replace(/\//g, "::");
71
59
  }
72
- export function readFile(name, readFileSyncImpl = readFileSync) {
73
- const fileName = toSavedFileName(name);
74
- try {
75
- return readFileSyncImpl(`${TEMP_DIRECTORY}/${fileName}`, "utf8");
76
- }
77
- catch (error) {
78
- return null;
79
- }
80
- }
81
- export function getEmptyMarkup() {
82
- return readFile("EMPTY");
83
- }
84
- export function tempDirectoryExists(existsSyncImpl = existsSync) {
85
- return existsSyncImpl(TEMP_DIRECTORY);
86
- }
87
- export function saveFile(name, data, writeFileImpl = writeFile) {
88
- const fileName = toSavedFileName(name);
89
- return new Promise((resolve) => {
90
- writeFileImpl(`${TEMP_DIRECTORY}/${fileName}`, data, () => {
91
- resolve();
92
- });
93
- });
94
- }
95
60
  export function removeFalseyValues(obj) {
96
61
  const filteredItems = Object.entries(obj).filter(([, value]) => value);
97
62
  return Object.fromEntries(filteredItems);
@@ -1,6 +1,5 @@
1
1
  import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
- import { getEnvironment, createTempDirectory, toSavedFileName, readFile, saveFile, removeFalseyValues, } from "./utils";
3
- import { TEMP_DIRECTORY } from ".";
2
+ import { getEnvironment, removeFalseyValues, toSavedFileName } from "./utils";
4
3
  const env = process.env;
5
4
  beforeEach(() => {
6
5
  vi.resetModules();
@@ -43,48 +42,11 @@ describe("getEnvironment()", () => {
43
42
  });
44
43
  });
45
44
  });
46
- describe("createTempDirectory()", () => {
47
- it("creates temp directory fresh", () => {
48
- const mkdirSyncMock = vi.fn();
49
- const existsSyncMock = vi.fn().mockReturnValue(false);
50
- expect(() => createTempDirectory(mkdirSyncMock, existsSyncMock)).not.toThrow();
51
- expect(mkdirSyncMock).toHaveBeenCalledWith(TEMP_DIRECTORY);
52
- });
53
- it("does not throw error when it already exists", () => {
54
- const mkdirSyncMock = vi.fn().mockImplementation(() => {
55
- throw new Error("Directory already exists");
56
- });
57
- const existsSyncMock = vi.fn().mockReturnValue(true);
58
- expect(() => createTempDirectory(mkdirSyncMock, existsSyncMock)).not.toThrow();
59
- expect(mkdirSyncMock).not.toHaveBeenCalledWith();
60
- });
61
- });
62
45
  describe("toSavedFileName()", () => {
63
46
  it("replaces slashes with double colons", () => {
64
47
  expect(toSavedFileName("/hey/there")).toEqual("hey::there");
65
48
  });
66
49
  });
67
- describe("readFile()", () => {
68
- it("reads the file", () => {
69
- const readFileSyncMock = vi.fn().mockReturnValue("file contents");
70
- expect(readFile("hey/there", readFileSyncMock)).toEqual("file contents");
71
- expect(readFileSyncMock).toHaveBeenCalledWith(`${TEMP_DIRECTORY}/hey::there`, "utf8");
72
- });
73
- it("returns null when file doesn't exist", () => {
74
- const readFileSyncMock = vi.fn().mockImplementation(() => {
75
- throw new Error("File not found");
76
- });
77
- expect(readFile("hey/there", readFileSyncMock)).toEqual(null);
78
- });
79
- });
80
- describe("saveFile()", () => {
81
- it("saves the file", async () => {
82
- const writeFileMock = vi.fn();
83
- const result = saveFile("hey/there", "file contents", writeFileMock);
84
- expect(writeFileMock).toHaveBeenCalledWith(`${TEMP_DIRECTORY}/hey::there`, "file contents", expect.any(Function));
85
- expect(result).toBeInstanceOf(Promise);
86
- });
87
- });
88
50
  describe("removeFalseyValues()", () => {
89
51
  it("should remove falsey values", () => {
90
52
  expect(removeFalseyValues({ a: 1, b: 0, d: null, e: "" })).toEqual({
@@ -1,5 +1,3 @@
1
1
  export type { CustomCopy } from "./markupFetcher";
2
- export declare const TEMP_DIRECTORY: string;
3
2
  export { markupFetcher, fetchAll } from "./markupFetcher";
4
- export { deleteTempDirectory, removeFalseyValues } from "./utils";
5
3
  export { log, logError } from "./log";
@@ -17,6 +17,7 @@ export interface IFetchData {
17
17
  tz?: string;
18
18
  baseUrl?: string;
19
19
  environment?: string;
20
+ dateFormat?: string;
20
21
  copy?: {
21
22
  copy_confirmation_message?: string;
22
23
  copy_submit_button?: string;
@@ -47,9 +48,9 @@ interface IBatchResponse {
47
48
  total: number;
48
49
  };
49
50
  }
50
- export declare function fetchAll({ tz, domain, apiKey, baseUrl, environment, copy, }: IBatchFetchData, platform: string, fetchImplementation?: any, batchMarkupFetcherImpl?: any): Promise<void>;
51
+ export declare function fetchAll({ tz, dateFormat, domain, apiKey, baseUrl, environment, copy, }: IBatchFetchData, platform: string, fetchImplementation?: any, batchMarkupFetcherImpl?: any): Promise<void>;
51
52
  export declare function batchMarkupFetcher(platform: string, fetchImplementation?: typeof fetch): (args: IBatchFetchData) => Promise<IBatchResponse>;
52
- export declare function fetchFreshMarkup({ tz, path, domain, apiKey, baseUrl, environment, copy, }: IFetchData, fetchImplementation: typeof fetch, platform: string): Promise<string>;
53
- export declare function makeMarkupRequest<T extends Partial<IBatchFetchData & IFetchData>>({ tz, path, domain, apiKey, baseUrl, environment, page, copy, }: T, baseServicePath: string, fetchImplementation: typeof fetch, platform: string): Promise<Response>;
53
+ export declare function fetchFreshMarkup({ tz, path, copy, domain, apiKey, dateFormat, baseUrl, environment, }: IFetchData, fetchImplementation: typeof fetch, platform: string): Promise<string>;
54
+ export declare function makeMarkupRequest<T extends Partial<IBatchFetchData & IFetchData>>({ tz, path, page, domain, apiKey, dateFormat, copy, baseUrl, environment, }: T, baseServicePath: string, fetchImplementation: typeof fetch, platform: string): Promise<Response>;
54
55
  export declare function markupFetcher(platform: string, fetchImplementation?: typeof fetch): (args: IFetchData) => Promise<string>;
55
56
  export {};
@@ -0,0 +1,8 @@
1
+ import { existsSync, mkdirSync, readFileSync } from "fs";
2
+ export declare function getTempDirectory(): Promise<string>;
3
+ export declare function deleteTempDirectory(): Promise<void>;
4
+ export declare function createTempDirectory(mkdirSyncImpl?: typeof mkdirSync, existsSyncImpl?: typeof existsSync): Promise<void>;
5
+ export declare function readFile(name: any, readFileSyncImpl?: typeof readFileSync): Promise<string>;
6
+ export declare function getEmptyMarkup(): Promise<string>;
7
+ export declare function tempDirectoryExists(existsSyncImpl?: typeof existsSync): Promise<boolean>;
8
+ export declare function saveFile(name: string, data: string, writeFileImpl?: any): Promise<void>;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,13 +1,6 @@
1
- import { existsSync, mkdirSync, readFileSync } from "fs";
2
1
  export declare function isValidTimezone(tz: string): boolean;
3
2
  export declare function getEnvironment(): string;
4
3
  export declare function parseJson(json: string): any;
5
4
  export declare function unescapeHTML(str: any): any;
6
- export declare function deleteTempDirectory(): void;
7
- export declare function createTempDirectory(mkdirSyncImpl?: typeof mkdirSync, existsSyncImpl?: typeof existsSync): void;
8
5
  export declare function toSavedFileName(name: string): string;
9
- export declare function readFile(name: any, readFileSyncImpl?: typeof readFileSync): string;
10
- export declare function getEmptyMarkup(): string;
11
- export declare function tempDirectoryExists(existsSyncImpl?: typeof existsSync): boolean;
12
- export declare function saveFile(name: string, data: string, writeFileImpl?: any): Promise<void>;
13
6
  export declare function removeFalseyValues<T>(obj: T): Partial<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jam-comments/server-utilities",
3
- "version": "5.3.0",
3
+ "version": "5.5.0",
4
4
  "description": "Various JavaScript utilities for JamComments.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -24,9 +24,9 @@
24
24
  "devDependencies": {
25
25
  "@types/node": "^20.14.11",
26
26
  "prettier": "^3.3.3",
27
- "typescript": "^5.5.3",
27
+ "typescript": "^5.5.4",
28
28
  "vite": "^5.3.4",
29
- "vitest": "^2.0.3"
29
+ "vitest": "^2.0.4"
30
30
  },
31
31
  "publishConfig": {
32
32
  "access": "public"