@remix-run/cli 0.1.0 → 0.3.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/README.md +0 -3
- package/dist/lib/bootstrap-project.d.ts.map +1 -1
- package/dist/lib/bootstrap-project.js +32 -9
- package/dist/lib/cli.d.ts +29 -0
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js +33 -14
- package/dist/lib/commands/completion.d.ts.map +1 -1
- package/dist/lib/commands/completion.js +5 -1
- package/dist/lib/commands/doctor.js +18 -18
- package/dist/lib/commands/help.d.ts.map +1 -1
- package/dist/lib/commands/help.js +9 -33
- package/dist/lib/commands/routes.js +3 -3
- package/dist/lib/commands/test.d.ts +1 -1
- package/dist/lib/commands/test.d.ts.map +1 -1
- package/dist/lib/commands/test.js +8 -4
- package/dist/lib/completion.d.ts.map +1 -1
- package/dist/lib/completion.js +4 -106
- package/dist/lib/controller-files.d.ts +0 -1
- package/dist/lib/controller-files.d.ts.map +1 -1
- package/dist/lib/controller-files.js +3 -5
- package/dist/lib/controller-ownership.d.ts +9 -9
- package/dist/lib/controller-ownership.d.ts.map +1 -1
- package/dist/lib/controller-ownership.js +56 -91
- package/dist/lib/doctor/controller-findings.d.ts +1 -1
- package/dist/lib/doctor/controller-findings.d.ts.map +1 -1
- package/dist/lib/doctor/controller-findings.js +15 -87
- package/dist/lib/doctor/controller-fix-plans.d.ts.map +1 -1
- package/dist/lib/doctor/controller-fix-plans.js +13 -24
- package/dist/lib/doctor/controller-placeholders.d.ts +2 -3
- package/dist/lib/doctor/controller-placeholders.d.ts.map +1 -1
- package/dist/lib/doctor/controller-placeholders.js +18 -149
- package/dist/lib/doctor/controllers.js +1 -1
- package/dist/lib/doctor/project.js +60 -52
- package/dist/lib/doctor/types.d.ts +2 -2
- package/dist/lib/doctor/types.d.ts.map +1 -1
- package/dist/lib/errors.d.ts +0 -6
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +0 -11
- package/dist/lib/load-route-map-worker.js +17 -9
- package/dist/lib/route-map.d.ts +1 -1
- package/dist/lib/route-map.d.ts.map +1 -1
- package/dist/lib/route-map.js +29 -17
- package/package.json +4 -5
- package/src/lib/bootstrap-project.ts +39 -13
- package/src/lib/cli.ts +46 -15
- package/src/lib/commands/completion.ts +6 -1
- package/src/lib/commands/doctor.ts +18 -21
- package/src/lib/commands/help.ts +9 -43
- package/src/lib/commands/routes.ts +3 -3
- package/src/lib/commands/test.ts +10 -4
- package/src/lib/completion.ts +4 -151
- package/src/lib/controller-files.ts +4 -8
- package/src/lib/controller-ownership.ts +78 -141
- package/src/lib/doctor/controller-findings.ts +20 -97
- package/src/lib/doctor/controller-fix-plans.ts +13 -29
- package/src/lib/doctor/controller-placeholders.ts +17 -189
- package/src/lib/doctor/controllers.ts +1 -1
- package/src/lib/doctor/project.ts +60 -52
- package/src/lib/doctor/types.ts +1 -5
- package/src/lib/errors.ts +0 -12
- package/src/lib/load-route-map-worker.ts +19 -10
- package/src/lib/route-map.ts +61 -16
- package/template/.agents/skills/remix/SKILL.md +588 -0
- package/template/.agents/skills/remix/references/animate-elements.md +195 -0
- package/template/.agents/skills/remix/references/assets-and-browser-modules.md +130 -0
- package/template/.agents/skills/remix/references/auth-and-sessions.md +443 -0
- package/template/.agents/skills/remix/references/component-model.md +282 -0
- package/template/.agents/skills/remix/references/create-mixins.md +158 -0
- package/template/.agents/skills/remix/references/data-and-validation.md +379 -0
- package/template/.agents/skills/remix/references/hydration-frames-navigation.md +297 -0
- package/template/.agents/skills/remix/references/middleware-and-server.md +233 -0
- package/template/.agents/skills/remix/references/mixins-styling-events.md +213 -0
- package/template/.agents/skills/remix/references/routing-and-controllers.md +391 -0
- package/template/.agents/skills/remix/references/testing-patterns.md +172 -0
- package/{bootstrap → template}/AGENTS.md +13 -8
- package/template/README.md +29 -0
- package/template/app/actions/controller.tsx +18 -0
- package/template/app/assets/entry.ts +8 -0
- package/template/app/assets/prompt-button.tsx +163 -0
- package/template/app/assets.ts +20 -0
- package/template/app/middleware/render.tsx +43 -0
- package/template/app/router.ts +20 -0
- package/template/app/routes.ts +6 -0
- package/template/app/ui/document.tsx +33 -0
- package/template/app/ui/scaffold-home-page.tsx +527 -0
- package/template/gitignore +4 -0
- package/{bootstrap → template}/package.json +5 -6
- package/template/public/favicon.svg +11 -0
- package/{bootstrap → template}/server.ts +4 -5
- package/{bootstrap → template}/tsconfig.json +3 -3
- package/bootstrap/README.md +0 -27
- package/bootstrap/app/controllers/auth.tsx +0 -21
- package/bootstrap/app/controllers/home.tsx +0 -26
- package/bootstrap/app/router.ts +0 -10
- package/bootstrap/app/routes.ts +0 -6
- package/bootstrap/app/ui/document.tsx +0 -21
- package/bootstrap/app/ui/layout.tsx +0 -22
- package/bootstrap/app/utils/render.tsx +0 -7
- package/dist/lib/commands/skills.d.ts +0 -6
- package/dist/lib/commands/skills.d.ts.map +0 -1
- package/dist/lib/commands/skills.js +0 -222
- package/dist/lib/skills-cache.d.ts +0 -19
- package/dist/lib/skills-cache.d.ts.map +0 -1
- package/dist/lib/skills-cache.js +0 -89
- package/dist/lib/skills.d.ts +0 -30
- package/dist/lib/skills.d.ts.map +0 -1
- package/dist/lib/skills.js +0 -441
- package/src/lib/commands/skills.ts +0 -306
- package/src/lib/skills-cache.ts +0 -140
- package/src/lib/skills.ts +0 -706
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as fs from 'node:fs/promises';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { getOwnerCandidateForExtension, getOwnerFileExtension, } from "../controller-files.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ROOT_ROUTE_NAME } from "../controller-ownership.js";
|
|
5
|
+
import { renderControllerPlaceholder } from "./controller-placeholders.js";
|
|
5
6
|
const OWNER_EXTENSION_PRIORITY = ['.tsx', '.ts', '.jsx', '.js'];
|
|
6
7
|
export async function getControllerFixPlans(appRoot, tree, ownership) {
|
|
7
8
|
let routeNodesByName = getRouteNodesByName(tree);
|
|
@@ -31,51 +32,33 @@ export async function getControllerFixPlans(appRoot, tree, ownership) {
|
|
|
31
32
|
if (routeNode == null || entryPath == null) {
|
|
32
33
|
continue;
|
|
33
34
|
}
|
|
34
|
-
let contents =
|
|
35
|
-
? renderActionPlaceholder(routeNode, entryPath)
|
|
36
|
-
: renderControllerPlaceholder(routeNode, entryPath, resolvedEntryPathByRouteName);
|
|
35
|
+
let contents = renderControllerPlaceholder(routeNode, entryPath);
|
|
37
36
|
fixPlans.push({
|
|
38
37
|
code,
|
|
39
38
|
contents,
|
|
40
39
|
kind: 'create-file',
|
|
41
40
|
path: entryPath,
|
|
42
41
|
routeName: subtree.routeName,
|
|
43
|
-
suite: '
|
|
42
|
+
suite: 'actions',
|
|
44
43
|
});
|
|
45
44
|
}
|
|
46
45
|
return fixPlans;
|
|
47
46
|
}
|
|
48
47
|
function getFixCodeForSubtree(subtree) {
|
|
49
|
-
if (subtree.actualEntryPaths.length > 1
|
|
48
|
+
if (subtree.actualEntryPaths.length > 1) {
|
|
50
49
|
return null;
|
|
51
50
|
}
|
|
52
51
|
if (subtree.actualEntryPath != null) {
|
|
53
52
|
return null;
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
return 'wrong-owner-kind';
|
|
57
|
-
}
|
|
58
|
-
if (subtree.kind === 'controller') {
|
|
59
|
-
return subtree.claimedFilePaths.length > 0 ? 'incomplete-controller' : 'missing-owner';
|
|
60
|
-
}
|
|
61
|
-
if (subtree.claimedFilePaths.length > 0) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
return 'missing-owner';
|
|
54
|
+
return subtree.claimedFilePaths.length > 0 ? 'incomplete-controller' : 'missing-owner';
|
|
65
55
|
}
|
|
66
56
|
function inferOwnerExtension(subtree, ownership, hasTsconfig) {
|
|
67
57
|
let subtreeExtension = getMostCommonOwnerExtension(subtree.claimedRouteLocalFilePaths);
|
|
68
58
|
if (subtreeExtension != null) {
|
|
69
59
|
return subtreeExtension;
|
|
70
60
|
}
|
|
71
|
-
let
|
|
72
|
-
if (alternateExtension != null) {
|
|
73
|
-
return alternateExtension;
|
|
74
|
-
}
|
|
75
|
-
let projectExtension = getMostCommonOwnerExtension([
|
|
76
|
-
...ownership.scan.actionEntryPaths,
|
|
77
|
-
...ownership.scan.controllerEntryPaths,
|
|
78
|
-
]);
|
|
61
|
+
let projectExtension = getMostCommonOwnerExtension([...ownership.scan.controllerEntryPaths]);
|
|
79
62
|
if (projectExtension != null) {
|
|
80
63
|
return projectExtension;
|
|
81
64
|
}
|
|
@@ -106,6 +89,12 @@ function getMostCommonOwnerExtension(filePaths) {
|
|
|
106
89
|
}
|
|
107
90
|
function getRouteNodesByName(tree) {
|
|
108
91
|
let routeNodesByName = new Map();
|
|
92
|
+
routeNodesByName.set(ROOT_ROUTE_NAME, {
|
|
93
|
+
children: tree,
|
|
94
|
+
key: ROOT_ROUTE_NAME,
|
|
95
|
+
kind: 'group',
|
|
96
|
+
name: ROOT_ROUTE_NAME,
|
|
97
|
+
});
|
|
109
98
|
function visit(nodes) {
|
|
110
99
|
for (let node of nodes) {
|
|
111
100
|
routeNodesByName.set(node.name, node);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function renderControllerPlaceholder(routeNode: OwnershipRouteNode, entryPath: string, resolvedEntryPathByRouteName: Map<string, string>): string;
|
|
1
|
+
import { type OwnershipRouteNode } from '../controller-ownership.ts';
|
|
2
|
+
export declare function renderControllerPlaceholder(routeNode: OwnershipRouteNode, entryPath: string): string;
|
|
4
3
|
//# sourceMappingURL=controller-placeholders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller-placeholders.d.ts","sourceRoot":"","sources":["../../../src/lib/doctor/controller-placeholders.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"controller-placeholders.d.ts","sourceRoot":"","sources":["../../../src/lib/doctor/controller-placeholders.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAErF,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,kBAAkB,EAC7B,SAAS,EAAE,MAAM,GAChB,MAAM,CAyBR"}
|
|
@@ -1,92 +1,13 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import { getOwnerFileExtension } from "../controller-files.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
'break',
|
|
6
|
-
'case',
|
|
7
|
-
'catch',
|
|
8
|
-
'class',
|
|
9
|
-
'const',
|
|
10
|
-
'continue',
|
|
11
|
-
'debugger',
|
|
12
|
-
'default',
|
|
13
|
-
'delete',
|
|
14
|
-
'do',
|
|
15
|
-
'else',
|
|
16
|
-
'enum',
|
|
17
|
-
'export',
|
|
18
|
-
'extends',
|
|
19
|
-
'false',
|
|
20
|
-
'finally',
|
|
21
|
-
'for',
|
|
22
|
-
'function',
|
|
23
|
-
'if',
|
|
24
|
-
'implements',
|
|
25
|
-
'import',
|
|
26
|
-
'in',
|
|
27
|
-
'instanceof',
|
|
28
|
-
'interface',
|
|
29
|
-
'let',
|
|
30
|
-
'new',
|
|
31
|
-
'null',
|
|
32
|
-
'package',
|
|
33
|
-
'private',
|
|
34
|
-
'protected',
|
|
35
|
-
'public',
|
|
36
|
-
'return',
|
|
37
|
-
'static',
|
|
38
|
-
'super',
|
|
39
|
-
'switch',
|
|
40
|
-
'this',
|
|
41
|
-
'throw',
|
|
42
|
-
'true',
|
|
43
|
-
'try',
|
|
44
|
-
'typeof',
|
|
45
|
-
'var',
|
|
46
|
-
'void',
|
|
47
|
-
'while',
|
|
48
|
-
'with',
|
|
49
|
-
'yield',
|
|
50
|
-
]);
|
|
51
|
-
export function renderActionPlaceholder(routeNode, entryPath) {
|
|
52
|
-
let routeMessage = `TODO: implement routes.${routeNode.name}`;
|
|
53
|
-
let extension = getOwnerFileExtension(entryPath);
|
|
54
|
-
let exportName = getActionExportName(routeNode.key);
|
|
55
|
-
if (extension === '.js' || extension === '.jsx') {
|
|
56
|
-
return [
|
|
57
|
-
`export const ${exportName} = {`,
|
|
58
|
-
` handler() {`,
|
|
59
|
-
` return new Response(${JSON.stringify(routeMessage)})`,
|
|
60
|
-
` },`,
|
|
61
|
-
`}`,
|
|
62
|
-
'',
|
|
63
|
-
].join('\n');
|
|
64
|
-
}
|
|
65
|
-
let routeExpression = getRouteAccessExpression(routeNode.name);
|
|
66
|
-
let routesImportPath = getRelativeImportPath(entryPath, 'app/routes.ts');
|
|
67
|
-
let method = routeNode.method ?? 'ANY';
|
|
68
|
-
return [
|
|
69
|
-
`import type { BuildAction } from 'remix/fetch-router'`,
|
|
70
|
-
'',
|
|
71
|
-
`import type { routes } from '${routesImportPath}'`,
|
|
72
|
-
'',
|
|
73
|
-
`export const ${exportName}: BuildAction<'${method}', typeof ${routeExpression}> = {`,
|
|
74
|
-
` handler() {`,
|
|
75
|
-
` return new Response(${JSON.stringify(routeMessage)})`,
|
|
76
|
-
` },`,
|
|
77
|
-
`}`,
|
|
78
|
-
'',
|
|
79
|
-
].join('\n');
|
|
80
|
-
}
|
|
81
|
-
export function renderControllerPlaceholder(routeNode, entryPath, resolvedEntryPathByRouteName) {
|
|
3
|
+
import { ROOT_ROUTE_NAME } from "../controller-ownership.js";
|
|
4
|
+
export function renderControllerPlaceholder(routeNode, entryPath) {
|
|
82
5
|
let extension = getOwnerFileExtension(entryPath);
|
|
83
6
|
let lines = [];
|
|
84
|
-
let
|
|
85
|
-
|
|
7
|
+
let actionEntries = routeNode.children
|
|
8
|
+
.filter((childNode) => childNode.kind === 'route')
|
|
9
|
+
.map((childNode) => renderControllerActionEntry(childNode));
|
|
86
10
|
if (extension === '.js' || extension === '.jsx') {
|
|
87
|
-
if (childImports.length > 0) {
|
|
88
|
-
lines.push(...childImports, '');
|
|
89
|
-
}
|
|
90
11
|
lines.push('export default {', ' actions: {');
|
|
91
12
|
lines.push(...actionEntries);
|
|
92
13
|
lines.push(' },', '}', '');
|
|
@@ -94,57 +15,24 @@ export function renderControllerPlaceholder(routeNode, entryPath, resolvedEntryP
|
|
|
94
15
|
}
|
|
95
16
|
let routeExpression = getRouteAccessExpression(routeNode.name);
|
|
96
17
|
let routesImportPath = getRelativeImportPath(entryPath, 'app/routes.ts');
|
|
97
|
-
lines.push(`import
|
|
98
|
-
lines.push(`import
|
|
99
|
-
|
|
100
|
-
lines.push('', ...childImports);
|
|
101
|
-
}
|
|
102
|
-
lines.push('', 'export default {', ' actions: {');
|
|
18
|
+
lines.push(`import { createController } from 'remix/router'`, '');
|
|
19
|
+
lines.push(`import { routes } from '${routesImportPath}'`);
|
|
20
|
+
lines.push('', `export default createController(${routeExpression}, {`, ' actions: {');
|
|
103
21
|
lines.push(...actionEntries);
|
|
104
|
-
lines.push(' },',
|
|
22
|
+
lines.push(' },', '})', '');
|
|
105
23
|
return lines.join('\n');
|
|
106
24
|
}
|
|
107
|
-
function
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
let childEntryPath = resolvedEntryPathByRouteName.get(childNode.name);
|
|
114
|
-
if (childEntryPath == null) {
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
imports.push(`import ${getControllerImportName(childNode.key)} from '${getRelativeImportPath(entryPath, childEntryPath)}'`);
|
|
118
|
-
}
|
|
119
|
-
return imports;
|
|
120
|
-
}
|
|
121
|
-
function renderControllerActionEntry(childNode, entryPath, resolvedEntryPathByRouteName) {
|
|
122
|
-
if (childNode.kind === 'route') {
|
|
123
|
-
return [
|
|
124
|
-
` ${formatObjectKey(childNode.key)}() {`,
|
|
125
|
-
` return new Response(${JSON.stringify(`TODO: implement routes.${childNode.name}`)})`,
|
|
126
|
-
` },`,
|
|
127
|
-
].join('\n');
|
|
128
|
-
}
|
|
129
|
-
let childEntryPath = resolvedEntryPathByRouteName.get(childNode.name);
|
|
130
|
-
if (childEntryPath != null) {
|
|
131
|
-
return ` ${formatObjectKey(childNode.key)}: ${getControllerImportName(childNode.key)},`;
|
|
132
|
-
}
|
|
133
|
-
return ` ${formatObjectKey(childNode.key)}: ${renderInlineControllerPlaceholder(childNode)},`;
|
|
134
|
-
}
|
|
135
|
-
function renderInlineControllerPlaceholder(routeNode) {
|
|
136
|
-
let childEntries = routeNode.children.map((childNode) => childNode.kind === 'route'
|
|
137
|
-
? `${formatObjectKey(childNode.key)}() { return new Response(${JSON.stringify(`TODO: implement routes.${childNode.name}`)}) }`
|
|
138
|
-
: `${formatObjectKey(childNode.key)}: ${renderInlineControllerPlaceholder(childNode)}`);
|
|
139
|
-
return `{ actions: { ${childEntries.join(', ')} } }`;
|
|
140
|
-
}
|
|
141
|
-
function getControllerImportName(key) {
|
|
142
|
-
return `${toIdentifier(key)}Controller`;
|
|
143
|
-
}
|
|
144
|
-
function getActionExportName(key) {
|
|
145
|
-
return toIdentifier(key);
|
|
25
|
+
function renderControllerActionEntry(childNode) {
|
|
26
|
+
return [
|
|
27
|
+
` ${formatObjectKey(childNode.key)}() {`,
|
|
28
|
+
` return new Response(${JSON.stringify(`TODO: implement routes.${childNode.name}`)})`,
|
|
29
|
+
` },`,
|
|
30
|
+
].join('\n');
|
|
146
31
|
}
|
|
147
32
|
function getRouteAccessExpression(routeName) {
|
|
33
|
+
if (routeName === ROOT_ROUTE_NAME) {
|
|
34
|
+
return 'routes';
|
|
35
|
+
}
|
|
148
36
|
let segments = routeName.split('.');
|
|
149
37
|
let expression = 'routes';
|
|
150
38
|
for (let segment of segments) {
|
|
@@ -159,25 +47,6 @@ function getRelativeImportPath(fromFilePath, toFilePath) {
|
|
|
159
47
|
function formatObjectKey(key) {
|
|
160
48
|
return isIdentifier(key) ? key : JSON.stringify(key);
|
|
161
49
|
}
|
|
162
|
-
function toIdentifier(value) {
|
|
163
|
-
let parts = value.split(/[^A-Za-z0-9_$]+/).filter(Boolean);
|
|
164
|
-
if (parts.length === 0) {
|
|
165
|
-
return 'route';
|
|
166
|
-
}
|
|
167
|
-
let identifier = parts
|
|
168
|
-
.map((part, index) => index === 0 ? part.replace(/^./, (char) => char.toLowerCase()) : capitalize(part))
|
|
169
|
-
.join('');
|
|
170
|
-
if (!/^[A-Za-z_$]/.test(identifier)) {
|
|
171
|
-
return `route${capitalize(identifier)}`;
|
|
172
|
-
}
|
|
173
|
-
if (RESERVED_BINDING_IDENTIFIERS.has(identifier)) {
|
|
174
|
-
return `route${capitalize(identifier)}`;
|
|
175
|
-
}
|
|
176
|
-
return identifier;
|
|
177
|
-
}
|
|
178
|
-
function capitalize(value) {
|
|
179
|
-
return value.length === 0 ? value : `${value[0].toUpperCase()}${value.slice(1)}`;
|
|
180
|
-
}
|
|
181
50
|
function isIdentifier(value) {
|
|
182
51
|
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value);
|
|
183
52
|
}
|
|
@@ -39,7 +39,7 @@ export async function checkProject(projectRoot) {
|
|
|
39
39
|
}
|
|
40
40
|
export async function getProjectFixPlans(projectRoot) {
|
|
41
41
|
let routesFile = path.join(projectRoot, 'app', 'routes.ts');
|
|
42
|
-
let homeActionPath = normalizeRelativePath(path.join('app', '
|
|
42
|
+
let homeActionPath = normalizeRelativePath(path.join('app', 'actions', `controller${await inferHomeOwnerExtension(projectRoot)}`));
|
|
43
43
|
if (await pathExists(routesFile)) {
|
|
44
44
|
let routesSource = await fs.readFile(routesFile, 'utf8');
|
|
45
45
|
if (!hasOnlyWhitespaceAndComments(routesSource)) {
|
|
@@ -181,8 +181,8 @@ function hasOnlyWhitespaceAndComments(source) {
|
|
|
181
181
|
return true;
|
|
182
182
|
}
|
|
183
183
|
async function inferHomeOwnerExtension(projectRoot) {
|
|
184
|
-
let
|
|
185
|
-
let extensions = await collectOwnerExtensions(
|
|
184
|
+
let actionsDir = path.join(projectRoot, 'app', 'actions');
|
|
185
|
+
let extensions = await collectOwnerExtensions(actionsDir);
|
|
186
186
|
if (extensions.length > 0) {
|
|
187
187
|
return getMostCommonExtension(extensions);
|
|
188
188
|
}
|
|
@@ -239,7 +239,7 @@ function getMostCommonExtension(extensions) {
|
|
|
239
239
|
}
|
|
240
240
|
function renderDefaultRoutesFile() {
|
|
241
241
|
return [
|
|
242
|
-
`import { route } from 'remix/
|
|
242
|
+
`import { route } from 'remix/routes'`,
|
|
243
243
|
'',
|
|
244
244
|
'export const routes = route({',
|
|
245
245
|
` home: '/',`,
|
|
@@ -257,22 +257,24 @@ function renderDefaultHomeAction(entryPath) {
|
|
|
257
257
|
`import { html } from 'remix/html-template'`,
|
|
258
258
|
`import { createHtmlResponse } from 'remix/response/html'`,
|
|
259
259
|
'',
|
|
260
|
-
'export
|
|
261
|
-
'
|
|
262
|
-
'
|
|
263
|
-
'
|
|
264
|
-
' <
|
|
265
|
-
' <
|
|
266
|
-
'
|
|
267
|
-
'
|
|
268
|
-
'
|
|
269
|
-
'
|
|
270
|
-
' <
|
|
271
|
-
'
|
|
272
|
-
'
|
|
273
|
-
'
|
|
274
|
-
'
|
|
275
|
-
'
|
|
260
|
+
'export default {',
|
|
261
|
+
' actions: {',
|
|
262
|
+
' home() {',
|
|
263
|
+
' let page = html`',
|
|
264
|
+
' <html lang="en">',
|
|
265
|
+
' <head>',
|
|
266
|
+
' <meta charset="utf-8" />',
|
|
267
|
+
' <meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
268
|
+
' <title>Home</title>',
|
|
269
|
+
' </head>',
|
|
270
|
+
' <body>',
|
|
271
|
+
' <h1>Home</h1>',
|
|
272
|
+
' <p>Update app/routes.ts and app/actions/controller to keep building your app.</p>',
|
|
273
|
+
' </body>',
|
|
274
|
+
' </html>',
|
|
275
|
+
' `',
|
|
276
|
+
' return createHtmlResponse(page)',
|
|
277
|
+
' },',
|
|
276
278
|
' },',
|
|
277
279
|
'}',
|
|
278
280
|
'',
|
|
@@ -280,30 +282,32 @@ function renderDefaultHomeAction(entryPath) {
|
|
|
280
282
|
}
|
|
281
283
|
if (extension === '.ts') {
|
|
282
284
|
return [
|
|
283
|
-
`import
|
|
285
|
+
`import { createController } from 'remix/router'`,
|
|
284
286
|
`import { html } from 'remix/html-template'`,
|
|
285
287
|
`import { createHtmlResponse } from 'remix/response/html'`,
|
|
286
288
|
'',
|
|
287
|
-
`import
|
|
289
|
+
`import { routes } from '../routes.ts'`,
|
|
288
290
|
'',
|
|
289
|
-
`export
|
|
290
|
-
'
|
|
291
|
-
'
|
|
292
|
-
'
|
|
293
|
-
' <
|
|
294
|
-
' <
|
|
295
|
-
'
|
|
296
|
-
'
|
|
297
|
-
'
|
|
298
|
-
'
|
|
299
|
-
' <
|
|
300
|
-
'
|
|
301
|
-
'
|
|
302
|
-
'
|
|
303
|
-
'
|
|
304
|
-
'
|
|
291
|
+
`export default createController(routes, {`,
|
|
292
|
+
' actions: {',
|
|
293
|
+
' home() {',
|
|
294
|
+
' let page = html`',
|
|
295
|
+
' <html lang="en">',
|
|
296
|
+
' <head>',
|
|
297
|
+
' <meta charset="utf-8" />',
|
|
298
|
+
' <meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
299
|
+
' <title>Home</title>',
|
|
300
|
+
' </head>',
|
|
301
|
+
' <body>',
|
|
302
|
+
' <h1>Home</h1>',
|
|
303
|
+
' <p>Update app/routes.ts and app/actions/controller to keep building your app.</p>',
|
|
304
|
+
' </body>',
|
|
305
|
+
' </html>',
|
|
306
|
+
' `',
|
|
307
|
+
' return createHtmlResponse(page)',
|
|
308
|
+
' },',
|
|
305
309
|
' },',
|
|
306
|
-
|
|
310
|
+
`})`,
|
|
307
311
|
'',
|
|
308
312
|
].join('\n');
|
|
309
313
|
}
|
|
@@ -312,10 +316,12 @@ function renderDefaultHomeAction(entryPath) {
|
|
|
312
316
|
`import { renderToStream } from 'remix/ui/server'`,
|
|
313
317
|
`import { createHtmlResponse } from 'remix/response/html'`,
|
|
314
318
|
'',
|
|
315
|
-
'export
|
|
316
|
-
'
|
|
317
|
-
'
|
|
318
|
-
'
|
|
319
|
+
'export default {',
|
|
320
|
+
' actions: {',
|
|
321
|
+
' home() {',
|
|
322
|
+
' let page = <HomePage />',
|
|
323
|
+
' return createHtmlResponse(renderToStream(page))',
|
|
324
|
+
' },',
|
|
319
325
|
' },',
|
|
320
326
|
'}',
|
|
321
327
|
'',
|
|
@@ -329,7 +335,7 @@ function renderDefaultHomeAction(entryPath) {
|
|
|
329
335
|
' </head>',
|
|
330
336
|
' <body>',
|
|
331
337
|
' <h1>Home</h1>',
|
|
332
|
-
' <p>Update app/routes.ts and app/
|
|
338
|
+
' <p>Update app/routes.ts and app/actions/controller to keep building your app.</p>',
|
|
333
339
|
' </body>',
|
|
334
340
|
' </html>',
|
|
335
341
|
' )',
|
|
@@ -338,18 +344,20 @@ function renderDefaultHomeAction(entryPath) {
|
|
|
338
344
|
].join('\n');
|
|
339
345
|
}
|
|
340
346
|
return [
|
|
341
|
-
`import
|
|
347
|
+
`import { createController } from 'remix/router'`,
|
|
342
348
|
`import { renderToStream } from 'remix/ui/server'`,
|
|
343
349
|
`import { createHtmlResponse } from 'remix/response/html'`,
|
|
344
350
|
'',
|
|
345
|
-
`import
|
|
351
|
+
`import { routes } from '../routes.ts'`,
|
|
346
352
|
'',
|
|
347
|
-
`export
|
|
348
|
-
'
|
|
349
|
-
'
|
|
350
|
-
'
|
|
353
|
+
`export default createController(routes, {`,
|
|
354
|
+
' actions: {',
|
|
355
|
+
' home() {',
|
|
356
|
+
' let page = <HomePage />',
|
|
357
|
+
' return createHtmlResponse(renderToStream(page))',
|
|
358
|
+
' },',
|
|
351
359
|
' },',
|
|
352
|
-
|
|
360
|
+
`})`,
|
|
353
361
|
'',
|
|
354
362
|
'function HomePage() {',
|
|
355
363
|
' return () => (',
|
|
@@ -361,7 +369,7 @@ function renderDefaultHomeAction(entryPath) {
|
|
|
361
369
|
' </head>',
|
|
362
370
|
' <body>',
|
|
363
371
|
' <h1>Home</h1>',
|
|
364
|
-
' <p>Update app/routes.ts and app/
|
|
372
|
+
' <p>Update app/routes.ts and app/actions/controller to keep building your app.</p>',
|
|
365
373
|
' </body>',
|
|
366
374
|
' </html>',
|
|
367
375
|
' )',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type DoctorSuiteName = 'environment' | 'project' | '
|
|
1
|
+
export type DoctorSuiteName = 'environment' | 'project' | 'actions';
|
|
2
2
|
export type DoctorFindingSeverity = 'warn' | 'advice';
|
|
3
3
|
export type DoctorSuiteStatus = 'ok' | 'issues' | 'skipped';
|
|
4
|
-
export type DoctorFindingCode = 'project-root-not-found' | 'package-json-read-failed' | 'package-json-invalid' | 'node-engine-missing' | 'node-engine-unparseable' | 'node-version-unsupported' | 'remix-dependency-missing' | 'remix-install-missing' | 'routes-file-missing' | 'routes-export-missing' | 'route-map-invalid' | 'route-module-import-failed' | 'route-map-invalid-json' | 'route-map-loader-signal' | 'missing-owner' | '
|
|
4
|
+
export type DoctorFindingCode = 'project-root-not-found' | 'package-json-read-failed' | 'package-json-invalid' | 'node-engine-missing' | 'node-engine-unparseable' | 'node-version-unsupported' | 'remix-dependency-missing' | 'remix-install-missing' | 'routes-file-missing' | 'routes-export-missing' | 'route-map-invalid' | 'route-module-import-failed' | 'route-map-invalid-json' | 'route-map-loader-signal' | 'missing-owner' | 'duplicate-owner-file' | 'incomplete-controller' | 'orphan-controller' | 'orphan-route-directory';
|
|
5
5
|
export type DoctorFixKind = 'create-directory' | 'create-file' | 'update-file';
|
|
6
6
|
export interface DoctorFinding {
|
|
7
7
|
actualPath?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/doctor/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,SAAS,GAAG,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/doctor/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,CAAA;AACnE,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,QAAQ,CAAA;AACrD,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAA;AAE3D,MAAM,MAAM,iBAAiB,GACzB,wBAAwB,GACxB,0BAA0B,GAC1B,sBAAsB,GACtB,qBAAqB,GACrB,yBAAyB,GACzB,0BAA0B,GAC1B,0BAA0B,GAC1B,uBAAuB,GACvB,qBAAqB,GACrB,uBAAuB,GACvB,mBAAmB,GACnB,4BAA4B,GAC5B,wBAAwB,GACxB,yBAAyB,GACzB,eAAe,GACf,sBAAsB,GACtB,uBAAuB,GACvB,mBAAmB,GACnB,wBAAwB,CAAA;AAE5B,MAAM,MAAM,aAAa,GAAG,kBAAkB,GAAG,aAAa,GAAG,aAAa,CAAA;AAE9E,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,iBAAiB,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,KAAK,EAAE,eAAe,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,iBAAiB,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,aAAa,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,eAAe,CAAA;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,iBAAiB,CAAA;IACvB,IAAI,EAAE,aAAa,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,eAAe,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACjC,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,IAAI,EAAE,eAAe,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,iBAAiB,CAAA;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,iBAAiB,CAAC,EAAE,aAAa,EAAE,CAAA;IACnC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,eAAe,EACrB,QAAQ,EAAE,aAAa,EAAE,GACxB,iBAAiB,CAMnB;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAOjG"}
|
package/dist/lib/errors.d.ts
CHANGED
|
@@ -125,11 +125,6 @@ export declare const CLI_ERROR_DEFINITIONS: {
|
|
|
125
125
|
title: string;
|
|
126
126
|
fix: string;
|
|
127
127
|
};
|
|
128
|
-
unknownSkillsCommand: {
|
|
129
|
-
code: string;
|
|
130
|
-
title: string;
|
|
131
|
-
fix: string;
|
|
132
|
-
};
|
|
133
128
|
};
|
|
134
129
|
export declare class CliError extends Error {
|
|
135
130
|
code: string;
|
|
@@ -165,7 +160,6 @@ export declare function unknownArgument(argument: string): UsageError;
|
|
|
165
160
|
export declare function unknownCommand(command: string): UsageError;
|
|
166
161
|
export declare function unknownCompletionShell(shell: string): UsageError;
|
|
167
162
|
export declare function unknownHelpTopic(topic: string): UsageError;
|
|
168
|
-
export declare function unknownSkillsCommand(command: string): UsageError;
|
|
169
163
|
export declare function unexpectedExtraArgument(argument: string): UsageError;
|
|
170
164
|
export declare function renderCliError(error: unknown, options?: {
|
|
171
165
|
helpText?: string;
|
package/dist/lib/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AAE1F,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;CACd;AAOD,eAAO,MAAM,qBAAqB
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/errors.js
CHANGED
|
@@ -109,11 +109,6 @@ export const CLI_ERROR_DEFINITIONS = {
|
|
|
109
109
|
title: 'Unknown help topic',
|
|
110
110
|
fix: 'Run `remix help` to see available commands and help topics.',
|
|
111
111
|
},
|
|
112
|
-
unknownSkillsCommand: {
|
|
113
|
-
code: 'RMX_UNKNOWN_SKILLS_COMMAND',
|
|
114
|
-
title: 'Unknown skills command',
|
|
115
|
-
fix: 'Run `remix skills --help` to see available skills commands.',
|
|
116
|
-
},
|
|
117
112
|
};
|
|
118
113
|
export class CliError extends Error {
|
|
119
114
|
code;
|
|
@@ -269,12 +264,6 @@ export function unknownHelpTopic(topic) {
|
|
|
269
264
|
message: `Unknown help topic: ${topic}`,
|
|
270
265
|
});
|
|
271
266
|
}
|
|
272
|
-
export function unknownSkillsCommand(command) {
|
|
273
|
-
return createUsageError(CLI_ERROR_DEFINITIONS.unknownSkillsCommand, {
|
|
274
|
-
context: { command },
|
|
275
|
-
message: `Unknown skills command: ${command}`,
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
267
|
export function unexpectedExtraArgument(argument) {
|
|
279
268
|
return createUsageError(CLI_ERROR_DEFINITIONS.unexpectedExtraArgument, {
|
|
280
269
|
context: { argument },
|
|
@@ -30,7 +30,7 @@ async function loadRawRouteTree(routesFile) {
|
|
|
30
30
|
if (!('routes' in routeModule)) {
|
|
31
31
|
throw new Error(`Route module ${routesFile} must export a named "routes" value.`);
|
|
32
32
|
}
|
|
33
|
-
return normalizeRouteGroup(
|
|
33
|
+
return normalizeRouteGroup(routeModule.routes, [], new Map());
|
|
34
34
|
}
|
|
35
35
|
function normalizeRouteGroup(value, parentSegments, seen) {
|
|
36
36
|
if (!isPlainObject(value)) {
|
|
@@ -47,14 +47,15 @@ function normalizeRouteGroup(value, parentSegments, seen) {
|
|
|
47
47
|
return Object.entries(value).map(([key, entryValue]) => {
|
|
48
48
|
let nameSegments = [...parentSegments, key];
|
|
49
49
|
let name = nameSegments.join('.');
|
|
50
|
-
|
|
50
|
+
let routeLeaf = readRouteLeaf(entryValue);
|
|
51
|
+
if (routeLeaf !== undefined) {
|
|
51
52
|
return {
|
|
52
53
|
children: [],
|
|
53
54
|
key,
|
|
54
55
|
kind: 'route',
|
|
55
|
-
method:
|
|
56
|
+
method: routeLeaf.method,
|
|
56
57
|
name,
|
|
57
|
-
pattern:
|
|
58
|
+
pattern: routeLeaf.pattern,
|
|
58
59
|
};
|
|
59
60
|
}
|
|
60
61
|
if (isPlainObject(entryValue)) {
|
|
@@ -72,13 +73,20 @@ function normalizeRouteGroup(value, parentSegments, seen) {
|
|
|
72
73
|
seen.delete(value);
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
|
-
function
|
|
76
|
+
function readRouteLeaf(value) {
|
|
77
|
+
if (typeof value !== 'object' || value == null)
|
|
78
|
+
return undefined;
|
|
79
|
+
let method = Reflect.get(value, 'method');
|
|
80
|
+
let pattern = Reflect.get(value, 'pattern');
|
|
81
|
+
if (typeof method !== 'string' || !hasToString(pattern))
|
|
82
|
+
return undefined;
|
|
83
|
+
return { method, pattern: pattern.toString() };
|
|
84
|
+
}
|
|
85
|
+
function hasToString(value) {
|
|
76
86
|
return (typeof value === 'object' &&
|
|
77
87
|
value != null &&
|
|
78
|
-
|
|
79
|
-
typeof
|
|
80
|
-
Reflect.get(value, 'pattern') != null &&
|
|
81
|
-
typeof Reflect.get(Reflect.get(value, 'pattern'), 'source') === 'string');
|
|
88
|
+
'toString' in value &&
|
|
89
|
+
typeof value.toString === 'function');
|
|
82
90
|
}
|
|
83
91
|
function isPlainObject(value) {
|
|
84
92
|
if (typeof value !== 'object' || value == null) {
|
package/dist/lib/route-map.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-map.d.ts","sourceRoot":"","sources":["../../src/lib/route-map.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"route-map.d.ts","sourceRoot":"","sources":["../../src/lib/route-map.ts"],"names":[],"mappings":"AAqBA,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,WAAW,CAAA;AACvD,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,CAAA;AAEjD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,cAAc,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,iBAAiB,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,cAAc,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,aAAa,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,gBAAgB,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,gBAAgB,EAAE,CAAA;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,iBAAiB,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAsB,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,cAAc,CAAC,CAUvF;AAED,wBAAsB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAGjG;AAED,wBAAsB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAShG"}
|