@cedarjs/cli 6.0.0-canary.2839 → 6.0.0-canary.2841

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.
@@ -42,6 +42,7 @@ import { files as serviceFiles } from "../service/serviceHandler.js";
42
42
  import { customOrDefaultTemplatePath } from "../yargsHandlerHelpers.js";
43
43
  const SKIPPABLE_ASSETS = ["scaffold.css"];
44
44
  const PACKAGE_SET = "Set";
45
+ const PACKAGE_PRIVATE_SET = "PrivateSet";
45
46
  const getIdType = (model) => {
46
47
  return model.fields.find((field) => field.isId)?.type;
47
48
  };
@@ -512,6 +513,65 @@ const addHelperPackages = async (task) => {
512
513
  await removeWorkspacePackages("web", ["humanize-string"]);
513
514
  });
514
515
  };
516
+ const isAuthSetup = () => {
517
+ const extensions = ["ts", "js", "tsx", "jsx"];
518
+ return extensions.some(
519
+ (ext) => fs.existsSync(path.join(getPaths().web.src, "auth." + ext))
520
+ );
521
+ };
522
+ const ROUTE_TAG_RE = /<Route\s+([^>]*?)\/?>/g;
523
+ const extractRouteAttr = (tagAttrs, attrName) => tagAttrs.match(new RegExp(`\\b${attrName}=["']([^"']+)["']`))?.[1];
524
+ const getRoutesFileContent = () => {
525
+ const routesPath = getPaths().web.routes;
526
+ if (!fs.existsSync(routesPath)) {
527
+ return void 0;
528
+ }
529
+ return readFile(routesPath).toString();
530
+ };
531
+ const hasLoginRoute = () => {
532
+ const content = getRoutesFileContent();
533
+ if (!content) {
534
+ return false;
535
+ }
536
+ return Array.from(content.matchAll(ROUTE_TAG_RE)).some(
537
+ ([, attrs]) => extractRouteAttr(attrs, "name") === "login"
538
+ );
539
+ };
540
+ const findUnprotectedLandingPageRouteName = () => {
541
+ const content = getRoutesFileContent();
542
+ if (!content) {
543
+ return void 0;
544
+ }
545
+ const privateSetRanges = Array.from(
546
+ content.matchAll(/<PrivateSet\b[^>]*>([\s\S]*?)<\/PrivateSet>/g)
547
+ ).map((match) => ({
548
+ start: match.index ?? 0,
549
+ end: (match.index ?? 0) + match[0].length
550
+ }));
551
+ for (const match of content.matchAll(ROUTE_TAG_RE)) {
552
+ const [, attrs] = match;
553
+ if (extractRouteAttr(attrs, "path") !== "/") {
554
+ continue;
555
+ }
556
+ const tagStart = match.index ?? 0;
557
+ const isProtected = privateSetRanges.some(
558
+ (range) => tagStart >= range.start && tagStart < range.end
559
+ );
560
+ if (!isProtected) {
561
+ return extractRouteAttr(attrs, "name");
562
+ }
563
+ }
564
+ return void 0;
565
+ };
566
+ const getUnauthenticatedRedirectRoute = () => {
567
+ if (!isAuthSetup()) {
568
+ return void 0;
569
+ }
570
+ if (hasLoginRoute()) {
571
+ return "login";
572
+ }
573
+ return findUnprotectedLandingPageRouteName();
574
+ };
515
575
  const addSetImport = (task) => {
516
576
  const routesPath = getPaths().web.routes;
517
577
  const routesContent = readFile(routesPath).toString();
@@ -525,15 +585,19 @@ const addSetImport = (task) => {
525
585
  return void 0;
526
586
  }
527
587
  const routerImports = importContent.replace(/\s/g, "").split(",");
528
- if (routerImports.includes(PACKAGE_SET)) {
588
+ const namesToImport = [
589
+ PACKAGE_SET,
590
+ ...getUnauthenticatedRedirectRoute() ? [PACKAGE_PRIVATE_SET] : []
591
+ ].filter((name) => !routerImports.includes(name));
592
+ if (!namesToImport.length) {
529
593
  return "Skipping Set import";
530
594
  }
531
595
  const newRoutesContent = routesContent.replace(
532
596
  cedarRouterImport,
533
- importStart + spacing + PACKAGE_SET + `,` + spacing + importContent + importEnd
597
+ importStart + spacing + namesToImport.join("," + spacing) + `,` + spacing + importContent + importEnd
534
598
  );
535
599
  writeFile(routesPath, newRoutesContent, { overwriteExisting: true });
536
- return "Added Set import to Routes.{jsx,tsx}";
600
+ return `Added ${namesToImport.join(", ")} import to Routes.{jsx,tsx}`;
537
601
  };
538
602
  const addScaffoldSetToRouter = async (model, scaffoldPath) => {
539
603
  const templateNames = getTemplateStrings(model, scaffoldPath);
@@ -542,10 +606,12 @@ const addScaffoldSetToRouter = async (model, scaffoldPath) => {
542
606
  const titleTo = templateNames.pluralRouteName;
543
607
  const buttonLabel = `New ${nameVars.singularPascalName}`;
544
608
  const buttonTo = templateNames.newRouteName;
609
+ const unauthenticatedRoute = getUnauthenticatedRedirectRoute();
545
610
  return addRoutesToRouterTask(
546
611
  await routes({ model, path: scaffoldPath }),
547
612
  "ScaffoldLayout",
548
- { title, titleTo, buttonLabel, buttonTo }
613
+ { title, titleTo, buttonLabel, buttonTo },
614
+ unauthenticatedRoute ? { unauthenticated: unauthenticatedRoute } : void 0
549
615
  );
550
616
  };
551
617
  const tasks = ({
@@ -664,7 +730,10 @@ const splitPathAndModel = (pathSlashModel) => {
664
730
  };
665
731
  export {
666
732
  files,
733
+ getUnauthenticatedRedirectRoute,
667
734
  handler,
735
+ hasLoginRoute,
736
+ isAuthSetup,
668
737
  routes,
669
738
  shouldUseTailwindCSS,
670
739
  splitPathAndModel,
package/dist/lib/index.js CHANGED
@@ -305,20 +305,35 @@ const cleanupEmptyDirsTask = (files) => {
305
305
  })
306
306
  );
307
307
  };
308
- function wrapWithSet(routesContent, layout, routes, newLineAndIndent, props = {}) {
308
+ function wrapWithSet(routesContent, layout, routes, newLineAndIndent, props = {}, privateSetProps) {
309
309
  const [_, indentOne, indentTwo] = routesContent.match(
310
310
  /([ \t]*)<Router.*?>[^<]*[\r\n]+([ \t]+)/
311
311
  ) || ["", "", ""];
312
312
  const oneLevelIndent = indentTwo.slice(0, indentTwo.length - indentOne.length);
313
- const newRoutesWithExtraIndent = routes.map((route) => oneLevelIndent + route);
314
313
  const propsString = Object.entries(props).map((values) => `${values[0]}="${values[1]}"`).join(" ");
314
+ if (!privateSetProps) {
315
+ const newRoutesWithExtraIndent2 = routes.map(
316
+ (route) => oneLevelIndent + route
317
+ );
318
+ return [
319
+ `<Set wrap={${layout}}${propsString && " " + propsString}>`,
320
+ ...newRoutesWithExtraIndent2,
321
+ `</Set>`
322
+ ].join(newLineAndIndent);
323
+ }
324
+ const privateSetPropsString = Object.entries(privateSetProps).map((values) => `${values[0]}="${values[1]}"`).join(" ");
325
+ const newRoutesWithExtraIndent = routes.map(
326
+ (route) => oneLevelIndent + oneLevelIndent + route
327
+ );
315
328
  return [
316
- `<Set wrap={${layout}}${propsString && " " + propsString}>`,
329
+ `<PrivateSet${privateSetPropsString && " " + privateSetPropsString}>`,
330
+ `${oneLevelIndent}<Set wrap={${layout}}${propsString && " " + propsString}>`,
317
331
  ...newRoutesWithExtraIndent,
318
- `</Set>`
332
+ `${oneLevelIndent}</Set>`,
333
+ `</PrivateSet>`
319
334
  ].join(newLineAndIndent);
320
335
  }
321
- function addRoutesToRouterTask(routes, layout, setProps = {}) {
336
+ function addRoutesToRouterTask(routes, layout, setProps = {}, privateSetProps) {
322
337
  const cedarPaths = getPaths();
323
338
  const routesContent = readFile(cedarPaths.web.routes).toString();
324
339
  let newRoutes = routes.filter((route) => !routesContent.match(route));
@@ -342,7 +357,8 @@ ${route}`);
342
357
  layout,
343
358
  newRoutes,
344
359
  newLineAndIndent,
345
- setProps
360
+ setProps,
361
+ privateSetProps
346
362
  ) : newRoutes.join(newLineAndIndent);
347
363
  const newRoutesContent = routesContent.replace(
348
364
  routerStart,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/cli",
3
- "version": "6.0.0-canary.2839",
3
+ "version": "6.0.0-canary.2841",
4
4
  "description": "The CedarJS Command Line",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,17 +36,17 @@
36
36
  "@babel/preset-typescript": "7.29.7",
37
37
  "@babel/traverse": "7.29.7",
38
38
  "@babel/types": "7.29.7",
39
- "@cedarjs/api-server": "6.0.0-canary.2839",
40
- "@cedarjs/babel-config": "6.0.0-canary.2839",
41
- "@cedarjs/cli-helpers": "6.0.0-canary.2839",
42
- "@cedarjs/internal": "6.0.0-canary.2839",
43
- "@cedarjs/prerender": "6.0.0-canary.2839",
44
- "@cedarjs/project-config": "6.0.0-canary.2839",
45
- "@cedarjs/structure": "6.0.0-canary.2839",
46
- "@cedarjs/telemetry": "6.0.0-canary.2839",
47
- "@cedarjs/utils": "6.0.0-canary.2839",
48
- "@cedarjs/vite": "6.0.0-canary.2839",
49
- "@cedarjs/web-server": "6.0.0-canary.2839",
39
+ "@cedarjs/api-server": "6.0.0-canary.2841",
40
+ "@cedarjs/babel-config": "6.0.0-canary.2841",
41
+ "@cedarjs/cli-helpers": "6.0.0-canary.2841",
42
+ "@cedarjs/internal": "6.0.0-canary.2841",
43
+ "@cedarjs/prerender": "6.0.0-canary.2841",
44
+ "@cedarjs/project-config": "6.0.0-canary.2841",
45
+ "@cedarjs/structure": "6.0.0-canary.2841",
46
+ "@cedarjs/telemetry": "6.0.0-canary.2841",
47
+ "@cedarjs/utils": "6.0.0-canary.2841",
48
+ "@cedarjs/vite": "6.0.0-canary.2841",
49
+ "@cedarjs/web-server": "6.0.0-canary.2841",
50
50
  "@listr2/prompt-adapter-enquirer": "4.3.0",
51
51
  "@opentelemetry/api": "1.9.1",
52
52
  "@opentelemetry/core": "1.30.1",
@@ -94,7 +94,7 @@
94
94
  "yargs": "17.7.3"
95
95
  },
96
96
  "devDependencies": {
97
- "@cedarjs/framework-tools": "6.0.0-canary.2839",
97
+ "@cedarjs/framework-tools": "6.0.0-canary.2841",
98
98
  "@prisma/dmmf": "7.8.0",
99
99
  "@types/archiver": "^7.0.0",
100
100
  "memfs": "4.64.0",