@getcronit/pylon 3.0.0-canary-20250303143548.bb9615641321063a172cd6af0a5cd52e2a2bc0a1 → 3.0.0-canary-20250312165655.826d17474bf64dfdbd9e31dd76e4f3898d48a6d1

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/index.js CHANGED
@@ -650,7 +650,7 @@ app.use("*", async (c, next) => {
650
650
  });
651
651
  });
652
652
  });
653
- app.use("*", except(["/__pylon/static/*"], logger()));
653
+ app.use("*", except(["/__pylon/*"], logger()));
654
654
  app.use((c, next) => {
655
655
  c.req.id = crypto.randomUUID();
656
656
  return next();
@@ -1157,7 +1157,7 @@ var handler = (options) => {
1157
1157
  graphqlEndpoint: "/graphql",
1158
1158
  ...config,
1159
1159
  landingPage: false,
1160
- graphiql: !!config?.graphiql ? (req) => {
1160
+ graphiql: config?.graphiql !== false ? (req) => {
1161
1161
  return {
1162
1162
  shouldPersistHeaders: true,
1163
1163
  title: "Pylon Playground",
@@ -1207,784 +1207,7 @@ function getEnv() {
1207
1207
 
1208
1208
  // src/index.ts
1209
1209
  import { createPubSub } from "graphql-yoga";
1210
-
1211
- // src/plugins/use-pages/setup/index.tsx
1212
- import fs2 from "fs";
1213
- import path3 from "path";
1214
- import reactServer from "react-dom/server";
1215
- import { PassThrough, Readable } from "stream";
1216
-
1217
- // src/plugins/use-pages/setup/app-loader.tsx
1218
- import { useMemo } from "react";
1219
- import { jsx } from "react/jsx-runtime";
1220
- var AppLoader = (props) => {
1221
- props.client.useHydrateCache({ cacheSnapshot: props.pylonData.cacheSnapshot });
1222
- const data = props.client.useQuery();
1223
- const page = useMemo(() => {
1224
- const page2 = /* @__PURE__ */ jsx(
1225
- props.App,
1226
- {
1227
- pageProps: {
1228
- ...props.pylonData.pageProps,
1229
- data
1230
- }
1231
- }
1232
- );
1233
- return page2;
1234
- }, [props]);
1235
- return /* @__PURE__ */ jsx(props.Router, { ...props.routerProps, children: page });
1236
- };
1237
-
1238
- // src/plugins/use-pages/setup/index.tsx
1239
- import { trimTrailingSlash } from "hono/trailing-slash";
1240
- import { StaticRouter } from "react-router";
1241
- import { createHash } from "crypto";
1242
- import { tmpdir } from "os";
1243
- import { pipeline } from "stream/promises";
1244
- import { jsx as jsx2 } from "react/jsx-runtime";
1245
- var disableCacheMiddleware = async (c, next) => {
1246
- const env3 = getEnv();
1247
- if (env3.NODE_ENV === "development") {
1248
- c.header(
1249
- "Cache-Control",
1250
- "no-store, no-cache, must-revalidate, proxy-revalidate"
1251
- );
1252
- c.header("Pragma", "no-cache");
1253
- c.header("Expires", "0");
1254
- c.header("Surrogate-Control", "no-store");
1255
- }
1256
- return next();
1257
- };
1258
- var setup = (app2) => {
1259
- const pagesFilePath = path3.resolve(process.cwd(), ".pylon", "pages.json");
1260
- let pageRoutes = [];
1261
- try {
1262
- pageRoutes = JSON.parse(fs2.readFileSync(pagesFilePath, "utf-8"));
1263
- } catch (error) {
1264
- console.error("Error reading pages.json", error);
1265
- }
1266
- app2.use(trimTrailingSlash());
1267
- let App = void 0;
1268
- let client = void 0;
1269
- app2.on(
1270
- "GET",
1271
- pageRoutes.map((pageRoute) => pageRoute.slug),
1272
- disableCacheMiddleware,
1273
- async (c) => {
1274
- if (!App) {
1275
- const module = await import(`${process.cwd()}/.pylon/__pylon/pages/app.js`);
1276
- App = module.default;
1277
- }
1278
- if (!client) {
1279
- client = await import(`${process.cwd()}/.pylon/client/index.js`);
1280
- }
1281
- const pageProps = {
1282
- params: c.req.param(),
1283
- searchParams: c.req.query(),
1284
- path: c.req.path
1285
- };
1286
- let cacheSnapshot = void 0;
1287
- const prepared = await client.prepareReactRender(
1288
- /* @__PURE__ */ jsx2(
1289
- AppLoader,
1290
- {
1291
- Router: StaticRouter,
1292
- routerProps: {
1293
- location: c.req.path
1294
- },
1295
- App,
1296
- client,
1297
- pylonData: {
1298
- pageProps,
1299
- cacheSnapshot: void 0
1300
- }
1301
- }
1302
- )
1303
- );
1304
- cacheSnapshot = prepared.cacheSnapshot;
1305
- if (reactServer.renderToReadableStream) {
1306
- const stream = await reactServer.renderToReadableStream(
1307
- /* @__PURE__ */ jsx2(
1308
- AppLoader,
1309
- {
1310
- Router: StaticRouter,
1311
- routerProps: {
1312
- location: c.req.path
1313
- },
1314
- App,
1315
- client,
1316
- pylonData: {
1317
- pageProps,
1318
- cacheSnapshot: prepared.cacheSnapshot
1319
- }
1320
- }
1321
- ),
1322
- {
1323
- bootstrapModules: ["/__pylon/static/app.js"],
1324
- bootstrapScriptContent: `window.__PYLON_DATA__ = ${JSON.stringify({
1325
- pageProps,
1326
- cacheSnapshot
1327
- })}`
1328
- }
1329
- );
1330
- return c.body(stream);
1331
- } else if (reactServer.renderToPipeableStream) {
1332
- let pipeableToReadable2 = function(pipeable) {
1333
- const passThrough = new PassThrough();
1334
- pipeable.pipe(passThrough);
1335
- return Readable.toWeb(passThrough);
1336
- };
1337
- var pipeableToReadable = pipeableToReadable2;
1338
- const pipableStream = reactServer.renderToPipeableStream(
1339
- /* @__PURE__ */ jsx2(
1340
- AppLoader,
1341
- {
1342
- Router: StaticRouter,
1343
- routerProps: {
1344
- location: c.req.path
1345
- },
1346
- App,
1347
- client,
1348
- pylonData: {
1349
- pageProps,
1350
- cacheSnapshot: prepared.cacheSnapshot
1351
- }
1352
- }
1353
- ),
1354
- {
1355
- bootstrapModules: ["/__pylon/static/app.js"],
1356
- bootstrapScriptContent: `window.__PYLON_DATA__ = ${JSON.stringify({
1357
- pageProps,
1358
- cacheSnapshot
1359
- })}`,
1360
- onShellReady: () => {
1361
- c.header("Content-Type", "text/html");
1362
- }
1363
- }
1364
- );
1365
- const stream = pipeableToReadable2(pipableStream);
1366
- return c.body(stream);
1367
- }
1368
- }
1369
- );
1370
- const publicFilesPath = path3.resolve(
1371
- process.cwd(),
1372
- ".pylon",
1373
- "__pylon",
1374
- "public"
1375
- );
1376
- let publicFiles = [];
1377
- try {
1378
- publicFiles = fs2.readdirSync(publicFilesPath);
1379
- } catch (error) {
1380
- }
1381
- app2.on(
1382
- "GET",
1383
- publicFiles.map((file) => `/${file}`),
1384
- disableCacheMiddleware,
1385
- async (c) => {
1386
- const publicFilePath = path3.resolve(
1387
- process.cwd(),
1388
- ".pylon",
1389
- "__pylon",
1390
- "public",
1391
- c.req.path.replace("/", "")
1392
- );
1393
- try {
1394
- await fs2.promises.access(publicFilePath);
1395
- if (publicFilePath.endsWith(".js")) {
1396
- c.res.headers.set("Content-Type", "text/javascript");
1397
- } else if (publicFilePath.endsWith(".css")) {
1398
- c.res.headers.set("Content-Type", "text/css");
1399
- } else if (publicFilePath.endsWith(".html")) {
1400
- c.res.headers.set("Content-Type", "text/html");
1401
- } else if (publicFilePath.endsWith(".json")) {
1402
- c.res.headers.set("Content-Type", "application/json");
1403
- } else if (publicFilePath.endsWith(".png")) {
1404
- c.res.headers.set("Content-Type", "image/png");
1405
- } else if (publicFilePath.endsWith(".jpg") || publicFilePath.endsWith(".jpeg")) {
1406
- c.res.headers.set("Content-Type", "image/jpeg");
1407
- } else if (publicFilePath.endsWith(".gif")) {
1408
- c.res.headers.set("Content-Type", "image/gif");
1409
- } else if (publicFilePath.endsWith(".svg")) {
1410
- c.res.headers.set("Content-Type", "image/svg+xml");
1411
- } else if (publicFilePath.endsWith(".ico")) {
1412
- c.res.headers.set("Content-Type", "image/x-icon");
1413
- }
1414
- const stream = fs2.createReadStream(publicFilePath);
1415
- const a = Readable.toWeb(stream);
1416
- return c.body(a);
1417
- } catch {
1418
- return c.status(404);
1419
- }
1420
- }
1421
- );
1422
- app2.get("/__pylon/static/*", disableCacheMiddleware, async (c) => {
1423
- const filePath = path3.resolve(
1424
- process.cwd(),
1425
- ".pylon",
1426
- "__pylon",
1427
- "static",
1428
- c.req.path.replace("/__pylon/static/", "")
1429
- );
1430
- if (!fs2.existsSync(filePath)) {
1431
- return c.status(404);
1432
- }
1433
- if (filePath.endsWith(".js")) {
1434
- c.res.headers.set("Content-Type", "text/javascript");
1435
- } else if (filePath.endsWith(".css")) {
1436
- c.res.headers.set("Content-Type", "text/css");
1437
- } else if (filePath.endsWith(".html")) {
1438
- c.res.headers.set("Content-Type", "text/html");
1439
- } else if (filePath.endsWith(".json")) {
1440
- c.res.headers.set("Content-Type", "application/json");
1441
- } else if (filePath.endsWith(".png")) {
1442
- c.res.headers.set("Content-Type", "image/png");
1443
- } else if (filePath.endsWith(".jpg") || filePath.endsWith(".jpeg")) {
1444
- c.res.headers.set("Content-Type", "image/jpeg");
1445
- } else if (filePath.endsWith(".gif")) {
1446
- c.res.headers.set("Content-Type", "image/gif");
1447
- } else if (filePath.endsWith(".svg")) {
1448
- c.res.headers.set("Content-Type", "image/svg+xml");
1449
- } else if (filePath.endsWith(".ico")) {
1450
- c.res.headers.set("Content-Type", "image/x-icon");
1451
- }
1452
- const stream = fs2.createReadStream(filePath);
1453
- const a = Readable.toWeb(stream);
1454
- return c.body(a);
1455
- });
1456
- app2.get("/__pylon/image", async (c) => {
1457
- try {
1458
- let isSupportedFormat2 = function(format2) {
1459
- const supportedFormats = sharp.format;
1460
- return Object.keys(supportedFormats).includes(format2);
1461
- };
1462
- var isSupportedFormat = isSupportedFormat2;
1463
- const sharp = (await import("sharp")).default;
1464
- const { src, w, h, q = "75", format = "webp" } = c.req.query();
1465
- const queryStringHash = createHash("sha256").update(JSON.stringify(c.req.query())).digest("hex");
1466
- if (!src) {
1467
- return c.json({ error: "Missing parameters." }, 400);
1468
- }
1469
- let imagePath = path3.join(process.cwd(), ".pylon", src);
1470
- if (src.startsWith("http://") || src.startsWith("https://")) {
1471
- imagePath = await downloadImage(src);
1472
- }
1473
- try {
1474
- await fs2.promises.access(imagePath);
1475
- } catch {
1476
- return c.json({ error: "Image not found" }, 404);
1477
- }
1478
- const metadata = await sharp(imagePath).metadata();
1479
- if (!metadata.width || !metadata.height) {
1480
- return c.json(
1481
- {
1482
- error: "Invalid image metadata. Width and height are required for resizing."
1483
- },
1484
- 400
1485
- );
1486
- }
1487
- const { width: finalWidth, height: finalHeight } = calculateDimensions(
1488
- metadata.width,
1489
- metadata.height,
1490
- w ? parseInt(w) : void 0,
1491
- h ? parseInt(h) : void 0
1492
- );
1493
- const cachePath = path3.join(IMAGE_CACHE_DIR, queryStringHash);
1494
- let imageFormat = format.toLowerCase();
1495
- if (!isSupportedFormat2(imageFormat)) {
1496
- throw new Error("Unsupported image format");
1497
- }
1498
- const quality = parseInt(q);
1499
- if (IS_IMAGE_CACHE_POSSIBLE) {
1500
- const image = await sharp(imagePath).resize(finalWidth, finalHeight).toFormat(imageFormat, {
1501
- quality
1502
- }).toFile(cachePath);
1503
- c.res.headers.set("Content-Type", getContentType(image.format));
1504
- return c.body(
1505
- Readable.toWeb(
1506
- fs2.createReadStream(cachePath)
1507
- )
1508
- );
1509
- } else {
1510
- const image = await sharp(imagePath).resize(finalWidth, finalHeight).toFormat(imageFormat, {
1511
- quality
1512
- }).toBuffer({ resolveWithObject: true });
1513
- c.res.headers.set("Content-Type", getContentType(image.info.format));
1514
- return c.body(image.data);
1515
- }
1516
- } catch (error) {
1517
- console.error("Error processing the image:", error);
1518
- return c.json({ error: "Error processing the image" }, 500);
1519
- }
1520
- });
1521
- };
1522
- var IMAGE_CACHE_DIR = path3.join(process.cwd(), ".cache/__pylon/images");
1523
- var IS_IMAGE_CACHE_POSSIBLE = true;
1524
- try {
1525
- await fs2.promises.mkdir(IMAGE_CACHE_DIR, { recursive: true });
1526
- } catch (error) {
1527
- IS_IMAGE_CACHE_POSSIBLE = false;
1528
- }
1529
- var calculateDimensions = (originalWidth, originalHeight, width, height) => {
1530
- if (!width && !height) {
1531
- return { width: originalWidth, height: originalHeight };
1532
- }
1533
- if (width && !height) {
1534
- height = Math.round(width * originalHeight / originalWidth);
1535
- } else if (height && !width) {
1536
- width = Math.round(height * originalWidth / originalHeight);
1537
- }
1538
- return { width, height };
1539
- };
1540
- var getContentType = (format) => {
1541
- switch (format.toLowerCase()) {
1542
- case "webp":
1543
- return "image/webp";
1544
- case "jpeg":
1545
- case "jpg":
1546
- return "image/jpeg";
1547
- case "png":
1548
- return "image/png";
1549
- case "gif":
1550
- return "image/gif";
1551
- case "svg":
1552
- return "image/svg+xml";
1553
- default:
1554
- return "application/octet-stream";
1555
- }
1556
- };
1557
- var downloadImage = async (url) => {
1558
- const response = await fetch(url);
1559
- if (!response.ok)
1560
- throw new Error(`Failed to download image: ${response.statusText}`);
1561
- const ext = path3.extname(new URL(url).pathname) || ".jpg";
1562
- const tempFilePath = path3.join(tmpdir(), `image-${Date.now()}${ext}`);
1563
- const fileStream = fs2.createWriteStream(tempFilePath);
1564
- await pipeline(response.body, fileStream);
1565
- return tempFilePath;
1566
- };
1567
-
1568
- // src/plugins/use-pages/build/index.ts
1569
- import path7 from "path";
1570
-
1571
- // src/plugins/use-pages/build/app-utils.ts
1572
- import path4 from "path";
1573
- import glob from "tiny-glob";
1574
- function fnv1aHash(str) {
1575
- let hash = 2166136261;
1576
- for (let i = 0; i < str.length; i++) {
1577
- hash ^= str.charCodeAt(i);
1578
- hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
1579
- }
1580
- return (hash >>> 0).toString(16);
1581
- }
1582
- var APP_DIR = path4.join(process.cwd(), "pages");
1583
- async function getPageRoutes(dir = APP_DIR) {
1584
- const routes = [];
1585
- const pagePattern = path4.join(dir, "**/page.{ts,tsx,js}");
1586
- const layoutPattern = path4.join(dir, "**/layout.tsx");
1587
- const pageFiles = await glob(pagePattern);
1588
- const layoutFiles = await glob(layoutPattern);
1589
- for (const pagePath of pageFiles) {
1590
- const relativePagePath = path4.relative(APP_DIR, pagePath);
1591
- let slug = "/" + relativePagePath.replace(/page\.(ts|tsx|js)$/, "").replace(/\[([\w-]+)\]/g, ":$1");
1592
- slug = slug.replace(/\/$/, "");
1593
- const layouts = layoutFiles.filter((layout) => {
1594
- return pagePath.startsWith(layout.replace("layout.tsx", ""));
1595
- });
1596
- const layoutsWithoutRootLayout = layouts.slice(1);
1597
- routes.push({
1598
- pagePath,
1599
- slug: slug || "/",
1600
- layouts: layoutsWithoutRootLayout
1601
- });
1602
- }
1603
- return routes;
1604
- }
1605
- var generateAppFile = (pageRoutes) => {
1606
- const makePageMap = (routes) => {
1607
- const pageMap2 = {};
1608
- for (const route of routes) {
1609
- pageMap2[route.pagePath] = `Page${fnv1aHash(route.pagePath)}`;
1610
- }
1611
- return pageMap2;
1612
- };
1613
- const makeLayoutMap = (routes) => {
1614
- const layoutMap2 = {};
1615
- for (const route of routes) {
1616
- for (const layout of route.layouts) {
1617
- layoutMap2[layout] = `Layout${fnv1aHash(layout)}`;
1618
- }
1619
- }
1620
- return layoutMap2;
1621
- };
1622
- const pageMap = makePageMap(pageRoutes);
1623
- const layoutMap = makeLayoutMap(pageRoutes);
1624
- const importPages = Object.keys(pageMap).map((pagePath, index) => {
1625
- const importLocation = `../${pagePath}`.replace(".tsx", ".js");
1626
- const componentName = pageMap[pagePath];
1627
- return `const ${componentName} = lazy(() => import('${importLocation}'))
1628
- `;
1629
- }).join("\n");
1630
- const importLayouts = Object.keys(layoutMap).map((layoutPath, index) => {
1631
- const importLocation = `../${layoutPath}`.replace(".tsx", ".js");
1632
- const componentName = layoutMap[layoutPath];
1633
- return `const ${componentName} = lazy(() => import('${importLocation}'))
1634
- `;
1635
- }).join("\n");
1636
- const appComponent = `"use client";
1637
- import {lazy, Suspense} from 'react'
1638
- import { __PYLON_ROUTER_INTERNALS_DO_NOT_USE } from '@getcronit/pylon/pages';
1639
- const {Routes, Route} = __PYLON_ROUTER_INTERNALS_DO_NOT_USE
1640
- ${importPages}
1641
- const RootLayout = lazy(() => import('../pages/layout.js'))
1642
- ${importLayouts}
1643
-
1644
- const App: React.FC<{pageProps: any}> = ({pageProps}) => (
1645
- <RootLayout>
1646
- <meta charSet="utf-8" />
1647
- <meta name="viewport" content="width=device-width, initial-scale=1" />
1648
- <link rel="stylesheet" href="/__pylon/static/app.css" precedence="high" />
1649
- <Routes>
1650
- ${pageRoutes.map((route, index) => {
1651
- return `<Route key={${index}} index={${index === 0 ? "true" : "false"}} path="${route.slug}" element={
1652
- <Suspense fallback={<div>...</div>}>
1653
- ${route.layouts.reduceRight((child, layoutPath, layoutIndex) => {
1654
- const layoutName = layoutMap[layoutPath];
1655
- return `<${layoutName}>${child}</${layoutName}>`;
1656
- }, `<${pageMap[route.pagePath]} {...pageProps} />`)}
1657
-
1658
- </Suspense>} />`;
1659
- }).join("\n")}
1660
- </Routes>
1661
- </RootLayout>
1662
- );
1663
-
1664
- export default App;
1665
- `;
1666
- return appComponent;
1667
- };
1668
-
1669
- // src/plugins/use-pages/build/index.ts
1670
- import chokidar from "chokidar";
1671
- import fs6 from "fs/promises";
1672
- import esbuild from "esbuild";
1673
-
1674
- // src/plugins/use-pages/build/plugins/inject-app-hydration.ts
1675
- import path5 from "path";
1676
- import fs3 from "fs/promises";
1677
- var injectAppHydrationPlugin = {
1678
- name: "inject-hydration",
1679
- setup(build2) {
1680
- build2.onLoad({ filter: /.*/, namespace: "file" }, async (args) => {
1681
- if (args.path === path5.resolve(process.cwd(), ".pylon", "app.tsx")) {
1682
- let contents = await fs3.readFile(args.path, "utf-8");
1683
- const clientPath = path5.resolve(process.cwd(), ".pylon/client");
1684
- const pathToClient = path5.relative(path5.dirname(args.path), clientPath);
1685
- contents += `
1686
- import {hydrateRoot} from 'react-dom/client'
1687
- import * as client from './${pathToClient}'
1688
- import { __PYLON_ROUTER_INTERNALS_DO_NOT_USE } from '@getcronit/pylon/pages';
1689
- const {BrowserRouter} = __PYLON_ROUTER_INTERNALS_DO_NOT_USE
1690
- import React, {useMemo} from 'react'
1691
-
1692
- const pylonData = window.__PYLON_DATA__
1693
-
1694
- const AppLoader = (props: {
1695
- client: any
1696
- pylonData: {
1697
- pageProps: Omit<PageProps, 'data'>
1698
- cacheSnapshot?: any
1699
- }
1700
- App: React.FC<{
1701
- pageProps: PageProps
1702
- }>
1703
- Router: React.FC<any>
1704
- routerProps: any
1705
- }) => {
1706
- props.client.useHydrateCache({cacheSnapshot: props.pylonData.cacheSnapshot})
1707
-
1708
- const data = props.client.useQuery()
1709
- const page = useMemo(() => {
1710
- const page = (
1711
- <props.App
1712
- pageProps={{
1713
- ...props.pylonData.pageProps,
1714
- data
1715
- }}
1716
- />
1717
- )
1718
-
1719
- return page
1720
- }, [props])
1721
-
1722
- return <props.Router {...props.routerProps}>{page}</props.Router>
1723
- }
1724
-
1725
-
1726
- hydrateRoot(
1727
- document,
1728
- <AppLoader Router={BrowserRouter} client={client} pylonData={pylonData} App={App} />
1729
- )
1730
- `;
1731
- return {
1732
- loader: "tsx",
1733
- contents
1734
- };
1735
- }
1736
- });
1737
- }
1738
- };
1739
-
1740
- // src/plugins/use-pages/build/plugins/image-plugin.ts
1741
- import { createHash as createHash2 } from "crypto";
1742
- import path6 from "path";
1743
- import fs4 from "fs/promises";
1744
- var imagePlugin = {
1745
- name: "image-plugin",
1746
- setup(build2) {
1747
- const outdir = build2.initialOptions.outdir;
1748
- const publicPath = build2.initialOptions.publicPath;
1749
- if (!outdir || !publicPath) {
1750
- throw new Error("outdir and publicPath must be set in esbuild options");
1751
- }
1752
- build2.onResolve({ filter: /\.(png|jpe?g)$/ }, async (args) => {
1753
- const filePath = path6.resolve(args.resolveDir, args.path);
1754
- const fileName = path6.basename(filePath);
1755
- const extname = path6.extname(filePath);
1756
- const hash = createHash2("md5").update(filePath + await fs4.readFile(filePath)).digest("hex").slice(0, 8);
1757
- const newFilename = `${fileName}-${hash}${extname}`;
1758
- const newFilePath = path6.join(outdir, "media", newFilename);
1759
- await fs4.mkdir(path6.dirname(newFilePath), { recursive: true });
1760
- await fs4.copyFile(filePath, newFilePath);
1761
- return {
1762
- path: newFilePath,
1763
- namespace: "image"
1764
- };
1765
- });
1766
- build2.onLoad({ filter: /\.png$|\.jpg$/ }, async (args) => {
1767
- const sharp = (await import("sharp")).default;
1768
- const image = sharp(args.path);
1769
- const metadata = await image.metadata();
1770
- const url = `${publicPath}/media/${path6.basename(args.path)}`;
1771
- const searchParams = new URLSearchParams({});
1772
- if (metadata.width) {
1773
- searchParams.set("w", metadata.width.toString());
1774
- }
1775
- if (metadata.height) {
1776
- searchParams.set("h", metadata.height.toString());
1777
- }
1778
- const output = image.resize({
1779
- width: Math.min(metadata.width ?? 16, 16),
1780
- height: Math.min(metadata.height ?? 16, 16),
1781
- fit: "inside"
1782
- }).toFormat("webp", {
1783
- quality: 20,
1784
- alphaQuality: 20,
1785
- smartSubsample: true
1786
- });
1787
- const { data, info } = await output.toBuffer({ resolveWithObject: true });
1788
- const dataURIBase64 = `data:image/${info.format};base64,${data.toString(
1789
- "base64"
1790
- )}`;
1791
- if (dataURIBase64) {
1792
- searchParams.set("blurDataURL", dataURIBase64);
1793
- }
1794
- return {
1795
- contents: `${url}?${searchParams.toString()}`,
1796
- loader: "text"
1797
- };
1798
- });
1799
- }
1800
- };
1801
-
1802
- // src/plugins/use-pages/build/plugins/postcss-plugin.ts
1803
- import fs5 from "fs/promises";
1804
- import loadConfig from "postcss-load-config";
1805
- import postcss from "postcss";
1806
- var postcssPlugin = {
1807
- name: "postcss-plugin",
1808
- setup(build2) {
1809
- build2.onLoad({ filter: /.css$/, namespace: "file" }, async (args) => {
1810
- const { plugins, options } = await loadConfig();
1811
- const css = await fs5.readFile(args.path, "utf-8");
1812
- const result = await postcss(plugins).process(css, {
1813
- ...options,
1814
- from: args.path
1815
- }).then((result2) => result2);
1816
- return {
1817
- contents: result.css,
1818
- loader: "css"
1819
- };
1820
- });
1821
- }
1822
- };
1823
-
1824
- // src/plugins/use-pages/build/index.ts
1825
- var DIST_STATIC_DIR = path7.join(process.cwd(), ".pylon/__pylon/static");
1826
- var DIST_PAGES_DIR = path7.join(process.cwd(), ".pylon/__pylon/pages");
1827
- async function updateFileIfChanged(path8, newContent) {
1828
- try {
1829
- const currentContent = await fs6.readFile(path8, "utf8");
1830
- if (currentContent === newContent) {
1831
- return false;
1832
- }
1833
- } catch (err) {
1834
- if (err.code !== "ENOENT") throw err;
1835
- }
1836
- await fs6.writeFile(path8, newContent, "utf8");
1837
- return true;
1838
- }
1839
- var build = async () => {
1840
- const buildAppFile = async () => {
1841
- const pagesRoutes = await getPageRoutes();
1842
- const appContent = generateAppFile(pagesRoutes);
1843
- const pagesFile = path7.resolve(process.cwd(), ".pylon", "pages.json");
1844
- await updateFileIfChanged(pagesFile, JSON.stringify(pagesRoutes, null, 2));
1845
- const appFilePath = path7.resolve(process.cwd(), ".pylon", "app.tsx");
1846
- const state = await updateFileIfChanged(appFilePath, appContent);
1847
- if (state) {
1848
- }
1849
- };
1850
- const copyPublicDir = async () => {
1851
- const publicDir = path7.resolve(process.cwd(), "public");
1852
- const pylonPublicDir = path7.resolve(
1853
- process.cwd(),
1854
- ".pylon",
1855
- "__pylon",
1856
- "public"
1857
- );
1858
- try {
1859
- await fs6.access(publicDir);
1860
- await fs6.mkdir(pylonPublicDir, { recursive: true });
1861
- await fs6.cp(publicDir, pylonPublicDir, { recursive: true });
1862
- } catch (err) {
1863
- if (err.code !== "ENOENT") throw err;
1864
- }
1865
- };
1866
- const writeOnEndPlugin = {
1867
- name: "write-on-end",
1868
- setup(build2) {
1869
- build2.onEnd(async (result) => {
1870
- await Promise.all(
1871
- result.outputFiles.map(async (file) => {
1872
- await fs6.mkdir(path7.dirname(file.path), { recursive: true });
1873
- await updateFileIfChanged(file.path, file.text);
1874
- })
1875
- );
1876
- });
1877
- }
1878
- };
1879
- const nodePaths = [
1880
- path7.join(process.cwd(), "node_modules"),
1881
- path7.join(process.cwd(), "node_modules", "@getcronit/pylon/node_modules")
1882
- ];
1883
- let pagesWatcher = null;
1884
- const clientCtx = await esbuild.context({
1885
- sourcemap: "linked",
1886
- write: false,
1887
- metafile: true,
1888
- nodePaths,
1889
- absWorkingDir: process.cwd(),
1890
- plugins: [
1891
- injectAppHydrationPlugin,
1892
- imagePlugin,
1893
- postcssPlugin,
1894
- writeOnEndPlugin
1895
- ],
1896
- publicPath: "/__pylon/static",
1897
- assetNames: "assets/[name]-[hash]",
1898
- chunkNames: "chunks/[name]-[hash]",
1899
- format: "esm",
1900
- platform: "browser",
1901
- entryPoints: [".pylon/app.tsx"],
1902
- outdir: DIST_STATIC_DIR,
1903
- bundle: true,
1904
- splitting: true,
1905
- minify: true,
1906
- loader: {
1907
- // Map file extensions to the file loader
1908
- ".svg": "file",
1909
- ".woff": "file",
1910
- ".woff2": "file"
1911
- },
1912
- define: {
1913
- "process.env.NODE_ENV": JSON.stringify(
1914
- process.env.NODE_ENV || "development"
1915
- )
1916
- },
1917
- mainFields: ["browser", "module", "main"]
1918
- });
1919
- const serverCtx = await esbuild.context({
1920
- sourcemap: "inline",
1921
- write: false,
1922
- absWorkingDir: process.cwd(),
1923
- nodePaths,
1924
- plugins: [imagePlugin, postcssPlugin, writeOnEndPlugin],
1925
- publicPath: "/__pylon/static",
1926
- assetNames: "assets/[name]-[hash]",
1927
- chunkNames: "chunks/[name]-[hash]",
1928
- format: "esm",
1929
- platform: "node",
1930
- entryPoints: [".pylon/app.tsx"],
1931
- outdir: DIST_PAGES_DIR,
1932
- bundle: true,
1933
- splitting: false,
1934
- external: ["@getcronit/pylon", "react", "react-dom", "gqty", "@gqty/react"],
1935
- minify: true,
1936
- loader: {
1937
- // Map file extensions to the file loader
1938
- ".svg": "file",
1939
- ".woff": "file",
1940
- ".woff2": "file"
1941
- },
1942
- define: {
1943
- "process.env.NODE_ENV": JSON.stringify(
1944
- process.env.NODE_ENV || "development"
1945
- )
1946
- },
1947
- mainFields: ["module", "main"]
1948
- });
1949
- return {
1950
- watch: async () => {
1951
- pagesWatcher = chokidar.watch("pages", { ignoreInitial: true });
1952
- pagesWatcher.on("all", async (event, path8) => {
1953
- if (["add", "change", "unlink"].includes(event)) {
1954
- await buildAppFile();
1955
- await copyPublicDir();
1956
- }
1957
- });
1958
- await Promise.all([clientCtx.watch(), serverCtx.watch()]);
1959
- },
1960
- dispose: async () => {
1961
- if (pagesWatcher) {
1962
- pagesWatcher.close();
1963
- }
1964
- Promise.all([clientCtx.dispose(), serverCtx.dispose()]);
1965
- },
1966
- rebuild: async () => {
1967
- await buildAppFile();
1968
- await copyPublicDir();
1969
- await Promise.all([clientCtx.rebuild(), serverCtx.rebuild()]);
1970
- return {};
1971
- },
1972
- cancel: async () => {
1973
- if (pagesWatcher) {
1974
- await pagesWatcher.close();
1975
- }
1976
- await Promise.all([clientCtx.cancel(), serverCtx.cancel()]);
1977
- }
1978
- };
1979
- };
1980
-
1981
- // src/plugins/use-pages/index.ts
1982
- function usePages() {
1983
- return {
1984
- setup,
1985
- build
1986
- };
1987
- }
1210
+ import { usePages } from "@getcronit/pylon-pages";
1988
1211
  export {
1989
1212
  ServiceError,
1990
1213
  app,