@gyoll/builder 0.6.0 → 0.7.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.
@@ -29,7 +29,7 @@ async function scanRoutes(routesDir) {
29
29
  const routes = await walkDirectory(routesDir, routesDir);
30
30
  return routes;
31
31
  }
32
- async function walkDirectory(dir, baseDir, segments = [], parentLayouts = []) {
32
+ async function walkDirectory(dir, baseDir, segments = [], parentLayouts = [], activeGuard = null) {
33
33
  const entries = await import_promises.default.readdir(dir, { withFileTypes: true });
34
34
  const files = entries.filter((e) => e.isFile());
35
35
  const dirs = entries.filter((e) => e.isDirectory());
@@ -38,19 +38,22 @@ async function walkDirectory(dir, baseDir, segments = [], parentLayouts = []) {
38
38
  if (routeFiles.layout) {
39
39
  currentLayouts.push(import_path.default.relative(baseDir, routeFiles.layout));
40
40
  }
41
+ let currentGuard = activeGuard;
42
+ if (routeFiles.guard) {
43
+ currentGuard = import_path.default.relative(baseDir, routeFiles.guard);
44
+ }
41
45
  const routes = [];
42
46
  if (routeFiles.page) {
43
- const pathInfo = buildRoutePath(segments);
44
47
  const route = {
45
- path: pathInfo.path,
48
+ path: buildRoutePath(segments),
46
49
  component: import_path.default.relative(baseDir, routeFiles.page)
47
50
  };
48
- if (pathInfo.catchAllParam) {
49
- route.catchAllParam = pathInfo.catchAllParam;
50
- }
51
51
  if (currentLayouts.length > 0) {
52
52
  route.layouts = [...currentLayouts];
53
53
  }
54
+ if (currentGuard) {
55
+ route.guard = import_path.default.relative(baseDir, currentGuard);
56
+ }
54
57
  if (routeFiles.error) {
55
58
  route.error = import_path.default.relative(baseDir, routeFiles.error);
56
59
  }
@@ -66,7 +69,8 @@ async function walkDirectory(dir, baseDir, segments = [], parentLayouts = []) {
66
69
  subdirPath,
67
70
  baseDir,
68
71
  [...segments, segment],
69
- currentLayouts
72
+ currentLayouts,
73
+ currentGuard
70
74
  );
71
75
  routes.push(...childRoutes);
72
76
  }
@@ -75,6 +79,7 @@ async function walkDirectory(dir, baseDir, segments = [], parentLayouts = []) {
75
79
  function collectRouteFiles(files, dir) {
76
80
  const routeFiles = {
77
81
  page: null,
82
+ guard: null,
78
83
  layout: null,
79
84
  error: null,
80
85
  loading: null
@@ -88,6 +93,8 @@ function collectRouteFiles(files, dir) {
88
93
  routeFiles.page = fullPath;
89
94
  } else if (/^layout\.(jsx?|tsx?)$/.test(name)) {
90
95
  routeFiles.layout = fullPath;
96
+ } else if (/^guard\.(jsx?|tsx?)$/.test(name)) {
97
+ routeFiles.guard = fullPath;
91
98
  } else if (/^error\.(jsx?|tsx?)$/.test(name)) {
92
99
  routeFiles.error = fullPath;
93
100
  } else if (/^loading\.(jsx?|tsx?)$/.test(name)) {
@@ -108,9 +115,8 @@ function parseSegment(segment) {
108
115
  if (/^\(.+\)$/.test(segment)) {
109
116
  return null;
110
117
  }
111
- const catchAllMatch = /^\[\.\.\.(.+)\]$/.exec(segment);
112
- if (catchAllMatch) {
113
- return { type: "catchall", param: catchAllMatch[1] };
118
+ if (/^\[\.\.\.(.+)\]$/.test(segment)) {
119
+ return "*";
114
120
  }
115
121
  if (/^\[(.+)\]$/.test(segment)) {
116
122
  const param = segment.slice(1, -1);
@@ -119,25 +125,11 @@ function parseSegment(segment) {
119
125
  return segment;
120
126
  }
121
127
  function buildRoutePath(segments) {
122
- const filtered = [];
123
- let catchAllParam = null;
124
- for (const segment of segments) {
125
- if (segment === null) {
126
- continue;
127
- }
128
- if (typeof segment === "object" && segment.type === "catchall") {
129
- catchAllParam = segment.param;
130
- filtered.push("*");
131
- } else {
132
- filtered.push(segment);
133
- }
134
- }
135
- const path3 = filtered.length === 0 ? "/" : "/" + filtered.join("/");
136
- const result = { path: path3 };
137
- if (catchAllParam) {
138
- result.catchAllParam = catchAllParam;
128
+ const filtered = segments.filter((s) => s !== null);
129
+ if (filtered.length === 0) {
130
+ return "/";
139
131
  }
140
- return result;
132
+ return "/" + filtered.join("/");
141
133
  }
142
134
  async function generateManifest(routes, outFile, routesDir) {
143
135
  const outDir = import_path.default.dirname(outFile);
@@ -151,6 +143,9 @@ async function generateManifest(routes, outFile, routesDir) {
151
143
  return `() => import("./${importPath}")`;
152
144
  });
153
145
  return `"layouts": [${transformed}]`;
146
+ }).replace(/"guard": "(.+?)"/g, (match, p1) => {
147
+ const importPath = import_path.default.join(relativeRoutesDir, p1).replace(/\\/g, "/");
148
+ return `"guard": () => import("./${importPath}")`;
154
149
  }).replace(/"error": "(.+?)"/g, (match, p1) => {
155
150
  const importPath = import_path.default.join(relativeRoutesDir, p1).replace(/\\/g, "/");
156
151
  return `"error": () => import("./${importPath}")`;
@@ -7,7 +7,7 @@ async function scanRoutes(routesDir) {
7
7
  const routes = await walkDirectory(routesDir, routesDir);
8
8
  return routes;
9
9
  }
10
- async function walkDirectory(dir, baseDir, segments = [], parentLayouts = []) {
10
+ async function walkDirectory(dir, baseDir, segments = [], parentLayouts = [], activeGuard = null) {
11
11
  const entries = await fs.readdir(dir, { withFileTypes: true });
12
12
  const files = entries.filter((e) => e.isFile());
13
13
  const dirs = entries.filter((e) => e.isDirectory());
@@ -16,19 +16,22 @@ async function walkDirectory(dir, baseDir, segments = [], parentLayouts = []) {
16
16
  if (routeFiles.layout) {
17
17
  currentLayouts.push(path.relative(baseDir, routeFiles.layout));
18
18
  }
19
+ let currentGuard = activeGuard;
20
+ if (routeFiles.guard) {
21
+ currentGuard = path.relative(baseDir, routeFiles.guard);
22
+ }
19
23
  const routes = [];
20
24
  if (routeFiles.page) {
21
- const pathInfo = buildRoutePath(segments);
22
25
  const route = {
23
- path: pathInfo.path,
26
+ path: buildRoutePath(segments),
24
27
  component: path.relative(baseDir, routeFiles.page)
25
28
  };
26
- if (pathInfo.catchAllParam) {
27
- route.catchAllParam = pathInfo.catchAllParam;
28
- }
29
29
  if (currentLayouts.length > 0) {
30
30
  route.layouts = [...currentLayouts];
31
31
  }
32
+ if (currentGuard) {
33
+ route.guard = path.relative(baseDir, currentGuard);
34
+ }
32
35
  if (routeFiles.error) {
33
36
  route.error = path.relative(baseDir, routeFiles.error);
34
37
  }
@@ -44,7 +47,8 @@ async function walkDirectory(dir, baseDir, segments = [], parentLayouts = []) {
44
47
  subdirPath,
45
48
  baseDir,
46
49
  [...segments, segment],
47
- currentLayouts
50
+ currentLayouts,
51
+ currentGuard
48
52
  );
49
53
  routes.push(...childRoutes);
50
54
  }
@@ -53,6 +57,7 @@ async function walkDirectory(dir, baseDir, segments = [], parentLayouts = []) {
53
57
  function collectRouteFiles(files, dir) {
54
58
  const routeFiles = {
55
59
  page: null,
60
+ guard: null,
56
61
  layout: null,
57
62
  error: null,
58
63
  loading: null
@@ -66,6 +71,8 @@ function collectRouteFiles(files, dir) {
66
71
  routeFiles.page = fullPath;
67
72
  } else if (/^layout\.(jsx?|tsx?)$/.test(name)) {
68
73
  routeFiles.layout = fullPath;
74
+ } else if (/^guard\.(jsx?|tsx?)$/.test(name)) {
75
+ routeFiles.guard = fullPath;
69
76
  } else if (/^error\.(jsx?|tsx?)$/.test(name)) {
70
77
  routeFiles.error = fullPath;
71
78
  } else if (/^loading\.(jsx?|tsx?)$/.test(name)) {
@@ -86,9 +93,8 @@ function parseSegment(segment) {
86
93
  if (/^\(.+\)$/.test(segment)) {
87
94
  return null;
88
95
  }
89
- const catchAllMatch = /^\[\.\.\.(.+)\]$/.exec(segment);
90
- if (catchAllMatch) {
91
- return { type: "catchall", param: catchAllMatch[1] };
96
+ if (/^\[\.\.\.(.+)\]$/.test(segment)) {
97
+ return "*";
92
98
  }
93
99
  if (/^\[(.+)\]$/.test(segment)) {
94
100
  const param = segment.slice(1, -1);
@@ -97,25 +103,11 @@ function parseSegment(segment) {
97
103
  return segment;
98
104
  }
99
105
  function buildRoutePath(segments) {
100
- const filtered = [];
101
- let catchAllParam = null;
102
- for (const segment of segments) {
103
- if (segment === null) {
104
- continue;
105
- }
106
- if (typeof segment === "object" && segment.type === "catchall") {
107
- catchAllParam = segment.param;
108
- filtered.push("*");
109
- } else {
110
- filtered.push(segment);
111
- }
112
- }
113
- const path3 = filtered.length === 0 ? "/" : "/" + filtered.join("/");
114
- const result = { path: path3 };
115
- if (catchAllParam) {
116
- result.catchAllParam = catchAllParam;
106
+ const filtered = segments.filter((s) => s !== null);
107
+ if (filtered.length === 0) {
108
+ return "/";
117
109
  }
118
- return result;
110
+ return "/" + filtered.join("/");
119
111
  }
120
112
  async function generateManifest(routes, outFile, routesDir) {
121
113
  const outDir = path.dirname(outFile);
@@ -129,6 +121,9 @@ async function generateManifest(routes, outFile, routesDir) {
129
121
  return `() => import("./${importPath}")`;
130
122
  });
131
123
  return `"layouts": [${transformed}]`;
124
+ }).replace(/"guard": "(.+?)"/g, (match, p1) => {
125
+ const importPath = path.join(relativeRoutesDir, p1).replace(/\\/g, "/");
126
+ return `"guard": () => import("./${importPath}")`;
132
127
  }).replace(/"error": "(.+?)"/g, (match, p1) => {
133
128
  const importPath = path.join(relativeRoutesDir, p1).replace(/\\/g, "/");
134
129
  return `"error": () => import("./${importPath}")`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gyoll/builder",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "description": "CLI tool for generating route manifests from file-system structure",
6
6
  "bin": {