@datawheel/bespoke 0.6.0-rc.4 → 0.6.0-rc.6

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.
Files changed (2) hide show
  1. package/dist/server.js +26 -144
  2. package/package.json +2 -3
package/dist/server.js CHANGED
@@ -26,8 +26,7 @@ import * as allIcons from '@tabler/icons-react';
26
26
  import NextCors from 'nextjs-cors';
27
27
  import imageType from 'image-type';
28
28
  import formidable from 'formidable';
29
- import puppeteer from 'puppeteer-core';
30
- import puppeteer2 from 'puppeteer';
29
+ import { chromium } from 'playwright-chromium';
31
30
  import DomParser from 'dom-parser';
32
31
  import path from 'path';
33
32
  import axiosRetry from 'axios-retry';
@@ -4221,114 +4220,6 @@ function endpointUpdateMyDataFactory(operations) {
4221
4220
  }
4222
4221
  }, []);
4223
4222
  }
4224
- async function generatePDF(path2) {
4225
- const width = 1920;
4226
- const height = 1080;
4227
- const maxTimeoutPerPage = 0;
4228
- try {
4229
- const browser = await puppeteer.launch({
4230
- args: [
4231
- `--window-size=${width},${height}`,
4232
- "--start-fullscreen"
4233
- ],
4234
- defaultViewport: { width, height },
4235
- headless: "shell",
4236
- ignoreHTTPSErrors: true
4237
- });
4238
- const url = new URL(path2);
4239
- const searchParams = new URLSearchParams(url.search);
4240
- searchParams.set("print", "true");
4241
- url.search = searchParams.toString();
4242
- const page = await browser.newPage();
4243
- await page.goto(url.toString(), { waitUntil: "networkidle0", timeout: maxTimeoutPerPage });
4244
- await page.waitForSelector("#bespoke-report", { timeout: maxTimeoutPerPage });
4245
- await page.evaluate(async () => {
4246
- await new Promise((resolve) => {
4247
- const scrollInterval = setInterval(() => {
4248
- window.scrollBy(0, window.innerHeight);
4249
- }, 100);
4250
- const checkNetworkActivity = () => {
4251
- const activeRequests = performance.getEntriesByType("resource").filter((entry) => entry.duration === 0);
4252
- return activeRequests.length === 0;
4253
- };
4254
- const checkInterval = setInterval(() => {
4255
- if (checkNetworkActivity()) {
4256
- clearInterval(scrollInterval);
4257
- clearInterval(checkInterval);
4258
- resolve();
4259
- }
4260
- }, 1e3);
4261
- });
4262
- });
4263
- const pdf = await page.pdf({
4264
- displayHeaderFooter: true,
4265
- footerTemplate: `
4266
- <div
4267
- style="
4268
- color: lightgray; border-top: solid lightgray 1px; font-size: 10px;
4269
- padding-top: 5px; text-align: center; width: 100%;
4270
- "
4271
- >
4272
- <p>Page <span class="pageNumber" /> of <span class="totalPages" /></p>
4273
- </div>`,
4274
- format: "A4",
4275
- // Letter,Legal,Tabloid,Ledger,A0,A1,A2,A3,A4,A5,A6
4276
- headerTemplate: `
4277
- <div
4278
- style="
4279
- color: lightgray; border-bottom: solid lightgray 1px; font-size: 10px;
4280
- padding-bottom: 5px; text-align: center; width: 100%;
4281
- "
4282
- >
4283
- <p class="url" />
4284
- </div>`,
4285
- // height: `${height}px`,
4286
- landscape: false,
4287
- margin: {
4288
- bottom: 70,
4289
- // minimum required for footer msg to display
4290
- left: 20,
4291
- right: 20,
4292
- top: 70
4293
- // minimum required for header msg to display
4294
- },
4295
- omitBackground: true,
4296
- pageRanges: "",
4297
- // All
4298
- // path: "./test.pdf" // Path to save the file
4299
- preferCSSPageSize: false,
4300
- // Give any CSS @page size declared in the page priority over what is declared in the width or height or format option.
4301
- printBackground: true,
4302
- scale: 1,
4303
- // From 0.1 to 2
4304
- tagged: false,
4305
- // Generate tagged (accessible) PDF.
4306
- timeout: 0
4307
- // width: `${width}px`,
4308
- });
4309
- await browser.close();
4310
- return pdf.toString("base64");
4311
- } catch (error) {
4312
- console.error("Error generating PDF:", error);
4313
- throw error;
4314
- }
4315
- }
4316
- function endpointDownloadReport() {
4317
- return endpoint("POST", "pdf", async (req, res) => {
4318
- const { slugs, path: path2 } = req.body;
4319
- if (!slugs || !path2) {
4320
- throw new BackendError(400, "Missing path parameter in request.");
4321
- } else {
4322
- const url = new URL(path2, req.headers["origin"]);
4323
- const pdf = await generatePDF(url);
4324
- return {
4325
- ok: true,
4326
- status: 200,
4327
- data: pdf
4328
- };
4329
- }
4330
- });
4331
- }
4332
4223
  var minimal_args = [
4333
4224
  "--autoplay-policy=user-gesture-required",
4334
4225
  "--disable-background-networking",
@@ -4368,56 +4259,47 @@ var minimal_args = [
4368
4259
  "--disable-dev-shm-usage",
4369
4260
  "--no-sandbox"
4370
4261
  ];
4371
- var blocked_domains = [
4372
- "google-analytics.com",
4373
- "googletagmanager.com"
4374
- ];
4262
+ var TIME = "playwright";
4375
4263
  async function generateImage(path2, section, format = "png", transparent = false) {
4376
4264
  const width = 1366;
4377
4265
  const height = 768;
4378
4266
  const maxTimeoutPerPage = 0;
4379
- console.time("puppeteer");
4267
+ console.time(TIME);
4380
4268
  try {
4381
- const browser = await puppeteer2.launch({
4269
+ const browser = await chromium.launch({
4270
+ executablePath: process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH,
4382
4271
  args: [
4383
4272
  `--window-size=${width},${height}`,
4384
4273
  ...minimal_args
4385
- ],
4386
- defaultViewport: { width, height, deviceScaleFactor: 2 },
4387
- ignoreHTTPSErrors: true,
4388
- headless: true
4274
+ ]
4389
4275
  });
4390
- console.timeLog("puppeteer", "Browser started");
4276
+ const context = await browser.newContext({
4277
+ viewport: { width, height },
4278
+ deviceScaleFactor: 2
4279
+ });
4280
+ console.timeLog(TIME, "Browser started");
4391
4281
  const url = new URL(path2);
4392
4282
  const searchParams = new URLSearchParams(url.search);
4393
4283
  url.search = searchParams.toString();
4394
- const page = await browser.newPage();
4395
- console.timeLog("puppeteer", "Creating page");
4284
+ const page = await context.newPage();
4285
+ console.timeLog(TIME, "Creating page");
4396
4286
  await page.addStyleTag({ content: ".bespoke-Section-container{ padding: 1rem !important }" });
4397
- await page.setRequestInterception(true);
4398
- page.on("request", (request) => {
4399
- const url2 = request.url();
4400
- if (blocked_domains.some((domain) => url2.includes(domain))) {
4401
- request.abort();
4402
- } else {
4403
- request.continue();
4404
- }
4405
- });
4406
- console.timeLog("puppeteer", "Setting request interceptor");
4407
- await page.goto(url.toString(), { waitUntil: "networkidle0", timeout: maxTimeoutPerPage });
4408
- console.timeLog("puppeteer", "Navigated to page");
4287
+ console.timeLog(TIME, "Setting request interceptor");
4288
+ await page.goto(url.toString(), { timeout: maxTimeoutPerPage });
4289
+ console.timeLog(TIME, "Navigated to page");
4409
4290
  await page.waitForSelector("#bespoke-report", { timeout: maxTimeoutPerPage });
4410
- console.timeLog("puppeteer", "Selector detected");
4291
+ console.timeLog(TIME, "Selector detected");
4292
+ await page.waitForLoadState("networkidle");
4411
4293
  if (transparent) {
4412
4294
  await page.$eval(`.bespoke-Section-${section}`, (el) => el["style"].background = "transparent");
4413
4295
  await page.evaluate(() => document.body.style.background = "transparent");
4414
- console.timeLog("puppeteer", "Added transparent background");
4296
+ console.timeLog(TIME, "Added transparent background");
4415
4297
  }
4416
4298
  if (format === "svg") {
4417
4299
  const element = await page.$(".d3plus-viz");
4418
4300
  const svg = await element?.evaluate((el) => el.outerHTML);
4419
- console.timeLog("puppeteer", "Finishing SVG");
4420
- console.timeEnd("puppeteer");
4301
+ console.timeLog(TIME, "Finishing SVG");
4302
+ console.timeEnd(TIME);
4421
4303
  await browser.close();
4422
4304
  return svg?.replace(/ {4}|[\t\n\r]/gm, "");
4423
4305
  } else {
@@ -4426,15 +4308,15 @@ async function generateImage(path2, section, format = "png", transparent = false
4426
4308
  type: "png",
4427
4309
  omitBackground: true
4428
4310
  });
4429
- console.timeLog("puppeteer", "Finishing PNG");
4430
- console.timeEnd("puppeteer");
4311
+ console.timeLog(TIME, "Finishing PNG");
4312
+ console.timeEnd(TIME);
4431
4313
  await browser.close();
4432
4314
  return screenshot;
4433
4315
  }
4434
4316
  } catch (error) {
4435
4317
  console.error("Error generating Image:", error);
4436
- console.timeLog("puppeteer", "Finishing with error");
4437
- console.timeEnd("puppeteer");
4318
+ console.timeLog(TIME, "Finishing with error");
4319
+ console.timeEnd(TIME);
4438
4320
  throw error;
4439
4321
  }
4440
4322
  }
@@ -4560,7 +4442,7 @@ function getEndpointMap(db) {
4560
4442
  endpointRevalidateReportFactory(api),
4561
4443
  endpointRevalidateUrlFactory(),
4562
4444
  endpointReadPrivateBlocksFactory(api),
4563
- endpointDownloadReport(),
4445
+ // endpointDownloadReport(),
4564
4446
  endpointExportImage(),
4565
4447
  endpointListIconsFactory(api, "tabler"),
4566
4448
  endpointReadIconFactory(api, "tabler"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/bespoke",
3
- "version": "0.6.0-rc.4",
3
+ "version": "0.6.0-rc.6",
4
4
  "description": "Content management system for creating automated data reports",
5
5
  "exports": {
6
6
  ".": {
@@ -103,9 +103,8 @@
103
103
  "nextjs-cors": "^2.1.1",
104
104
  "normalizr": "^3.6.2",
105
105
  "pg": "^8.7.3",
106
+ "playwright-chromium": "^1.44.1",
106
107
  "pretty-format": "^28.1.1",
107
- "puppeteer": "^22.10.0",
108
- "puppeteer-core": "^22.10.0",
109
108
  "react": "^18.2.0",
110
109
  "react-clipboard.js": "^2.0.16",
111
110
  "react-dom": "^18.2.0",