@nx/remix 0.0.0-pr-22179-271588f

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 (163) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +63 -0
  3. package/executors.json +14 -0
  4. package/generators.d.ts +14 -0
  5. package/generators.js +31 -0
  6. package/generators.json +90 -0
  7. package/index.d.ts +1 -0
  8. package/index.js +5 -0
  9. package/migrations.json +107 -0
  10. package/package.json +53 -0
  11. package/plugin.d.ts +1 -0
  12. package/plugin.js +6 -0
  13. package/plugins/component-testing/index.d.ts +30 -0
  14. package/plugins/component-testing/index.js +64 -0
  15. package/src/executors/build/build.impl.d.ts +5 -0
  16. package/src/executors/build/build.impl.js +109 -0
  17. package/src/executors/build/schema.d.ts +7 -0
  18. package/src/executors/build/schema.json +38 -0
  19. package/src/executors/serve/schema.d.ts +9 -0
  20. package/src/executors/serve/schema.json +41 -0
  21. package/src/executors/serve/serve.impl.d.ts +6 -0
  22. package/src/executors/serve/serve.impl.js +77 -0
  23. package/src/generators/action/action.impl.d.ts +3 -0
  24. package/src/generators/action/action.impl.js +39 -0
  25. package/src/generators/action/schema.d.ts +10 -0
  26. package/src/generators/action/schema.json +29 -0
  27. package/src/generators/application/__snapshots__/application.impl.spec.ts.snap +1487 -0
  28. package/src/generators/application/application.impl.d.ts +5 -0
  29. package/src/generators/application/application.impl.js +198 -0
  30. package/src/generators/application/files/common/README.md__tmpl__ +54 -0
  31. package/src/generators/application/files/common/app/nx-welcome.tsx__tmpl__ +886 -0
  32. package/src/generators/application/files/common/app/root.tsx__tmpl__ +32 -0
  33. package/src/generators/application/files/common/app/routes/_index.tsx__tmpl__ +9 -0
  34. package/src/generators/application/files/common/public/favicon.ico +0 -0
  35. package/src/generators/application/files/common/remix.config.js__tmpl__ +17 -0
  36. package/src/generators/application/files/common/remix.env.d.ts__tmpl__ +2 -0
  37. package/src/generators/application/files/common/tests/routes/_index.spec.tsx__tmpl__ +16 -0
  38. package/src/generators/application/files/common/tsconfig.app.json__tmpl__ +20 -0
  39. package/src/generators/application/files/common/tsconfig.json__tmpl__ +24 -0
  40. package/src/generators/application/files/integrated/.gitignore__tmpl__ +4 -0
  41. package/src/generators/application/files/integrated/package.json__tmpl__ +28 -0
  42. package/src/generators/application/lib/add-e2e.d.ts +3 -0
  43. package/src/generators/application/lib/add-e2e.js +66 -0
  44. package/src/generators/application/lib/index.d.ts +3 -0
  45. package/src/generators/application/lib/index.js +6 -0
  46. package/src/generators/application/lib/normalize-options.d.ts +10 -0
  47. package/src/generators/application/lib/normalize-options.js +37 -0
  48. package/src/generators/application/lib/update-unit-test-config.d.ts +2 -0
  49. package/src/generators/application/lib/update-unit-test-config.js +55 -0
  50. package/src/generators/application/schema.d.ts +16 -0
  51. package/src/generators/application/schema.json +68 -0
  52. package/src/generators/cypress-component-configuration/cypress-component-configuration.impl.d.ts +5 -0
  53. package/src/generators/cypress-component-configuration/cypress-component-configuration.impl.js +34 -0
  54. package/src/generators/cypress-component-configuration/files/cypress.config.ts__tmpl__ +6 -0
  55. package/src/generators/cypress-component-configuration/schema.d.ts +6 -0
  56. package/src/generators/cypress-component-configuration/schema.json +41 -0
  57. package/src/generators/error-boundary/__snapshots__/error-boundary.impl.spec.ts.snap +61 -0
  58. package/src/generators/error-boundary/error-boundary.impl.d.ts +3 -0
  59. package/src/generators/error-boundary/error-boundary.impl.js +12 -0
  60. package/src/generators/error-boundary/lib/add-v2-error-boundary.d.ts +3 -0
  61. package/src/generators/error-boundary/lib/add-v2-error-boundary.js +38 -0
  62. package/src/generators/error-boundary/lib/index.d.ts +2 -0
  63. package/src/generators/error-boundary/lib/index.js +5 -0
  64. package/src/generators/error-boundary/lib/normalize-options.d.ts +3 -0
  65. package/src/generators/error-boundary/lib/normalize-options.js +17 -0
  66. package/src/generators/error-boundary/schema.d.ts +11 -0
  67. package/src/generators/error-boundary/schema.json +37 -0
  68. package/src/generators/init/init.d.ts +5 -0
  69. package/src/generators/init/init.js +60 -0
  70. package/src/generators/init/schema.d.ts +7 -0
  71. package/src/generators/init/schema.json +33 -0
  72. package/src/generators/library/__snapshots__/library.impl.spec.ts.snap +157 -0
  73. package/src/generators/library/lib/add-tsconfig-entry-points.d.ts +3 -0
  74. package/src/generators/library/lib/add-tsconfig-entry-points.js +19 -0
  75. package/src/generators/library/lib/add-unit-testing.d.ts +3 -0
  76. package/src/generators/library/lib/add-unit-testing.js +32 -0
  77. package/src/generators/library/lib/index.d.ts +4 -0
  78. package/src/generators/library/lib/index.js +7 -0
  79. package/src/generators/library/lib/normalize-options.d.ts +7 -0
  80. package/src/generators/library/lib/normalize-options.js +29 -0
  81. package/src/generators/library/lib/update-buildable-config.d.ts +2 -0
  82. package/src/generators/library/lib/update-buildable-config.js +21 -0
  83. package/src/generators/library/library.impl.d.ts +6 -0
  84. package/src/generators/library/library.impl.js +45 -0
  85. package/src/generators/library/schema.d.ts +16 -0
  86. package/src/generators/library/schema.json +74 -0
  87. package/src/generators/loader/loader.impl.d.ts +3 -0
  88. package/src/generators/loader/loader.impl.js +39 -0
  89. package/src/generators/loader/schema.d.ts +10 -0
  90. package/src/generators/loader/schema.json +29 -0
  91. package/src/generators/meta/lib/v2.impl.d.ts +3 -0
  92. package/src/generators/meta/lib/v2.impl.js +28 -0
  93. package/src/generators/meta/meta.impl.d.ts +3 -0
  94. package/src/generators/meta/meta.impl.js +7 -0
  95. package/src/generators/meta/schema.d.ts +10 -0
  96. package/src/generators/meta/schema.json +29 -0
  97. package/src/generators/preset/lib/normalize-options.d.ts +11 -0
  98. package/src/generators/preset/lib/normalize-options.js +20 -0
  99. package/src/generators/preset/preset.impl.d.ts +3 -0
  100. package/src/generators/preset/preset.impl.js +32 -0
  101. package/src/generators/preset/schema.d.ts +4 -0
  102. package/src/generators/preset/schema.json +14 -0
  103. package/src/generators/resource-route/__snapshots__/resource-route.impl.spec.ts.snap +21 -0
  104. package/src/generators/resource-route/resource-route.impl.d.ts +3 -0
  105. package/src/generators/resource-route/resource-route.impl.js +41 -0
  106. package/src/generators/resource-route/schema.d.ts +13 -0
  107. package/src/generators/resource-route/schema.json +51 -0
  108. package/src/generators/route/__snapshots__/route.impl.spec.ts.snap +95 -0
  109. package/src/generators/route/route.impl.d.ts +3 -0
  110. package/src/generators/route/route.impl.js +78 -0
  111. package/src/generators/route/schema.d.ts +15 -0
  112. package/src/generators/route/schema.json +62 -0
  113. package/src/generators/setup/schema.json +14 -0
  114. package/src/generators/setup/setup.impl.d.ts +2 -0
  115. package/src/generators/setup/setup.impl.js +34 -0
  116. package/src/generators/setup-tailwind/__snapshots__/setup-tailwind.impl.spec.ts.snap +170 -0
  117. package/src/generators/setup-tailwind/files/app/tailwind.css__tpl__ +3 -0
  118. package/src/generators/setup-tailwind/files/tailwind.config.ts__tpl__ +13 -0
  119. package/src/generators/setup-tailwind/lib/index.d.ts +1 -0
  120. package/src/generators/setup-tailwind/lib/index.js +4 -0
  121. package/src/generators/setup-tailwind/lib/update-remix-config.d.ts +2 -0
  122. package/src/generators/setup-tailwind/lib/update-remix-config.js +35 -0
  123. package/src/generators/setup-tailwind/schema.d.ts +5 -0
  124. package/src/generators/setup-tailwind/schema.json +36 -0
  125. package/src/generators/setup-tailwind/setup-tailwind.impl.d.ts +3 -0
  126. package/src/generators/setup-tailwind/setup-tailwind.impl.js +34 -0
  127. package/src/generators/storybook-configuration/__snapshots__/storybook-configuration.impl.spec.ts.snap +73 -0
  128. package/src/generators/storybook-configuration/files/vite.config.ts__tpl__ +15 -0
  129. package/src/generators/storybook-configuration/schema.d.ts +16 -0
  130. package/src/generators/storybook-configuration/schema.json +89 -0
  131. package/src/generators/storybook-configuration/storybook-configuration.impl.d.ts +4 -0
  132. package/src/generators/storybook-configuration/storybook-configuration.impl.js +26 -0
  133. package/src/generators/style/schema.d.ts +10 -0
  134. package/src/generators/style/schema.json +36 -0
  135. package/src/generators/style/style.impl.d.ts +3 -0
  136. package/src/generators/style/style.impl.js +61 -0
  137. package/src/generators/utils/update-dependencies.d.ts +2 -0
  138. package/src/generators/utils/update-dependencies.js +21 -0
  139. package/src/plugins/__snapshots__/plugin.spec.ts.snap +113 -0
  140. package/src/plugins/plugin.d.ts +9 -0
  141. package/src/plugins/plugin.js +136 -0
  142. package/src/utils/create-watch-paths.d.ts +8 -0
  143. package/src/utils/create-watch-paths.js +40 -0
  144. package/src/utils/get-default-export-name.d.ts +2 -0
  145. package/src/utils/get-default-export-name.js +8 -0
  146. package/src/utils/get-default-export.d.ts +2 -0
  147. package/src/utils/get-default-export.js +15 -0
  148. package/src/utils/insert-import.d.ts +4 -0
  149. package/src/utils/insert-import.js +54 -0
  150. package/src/utils/insert-statement-after-imports.d.ts +5 -0
  151. package/src/utils/insert-statement-after-imports.js +28 -0
  152. package/src/utils/insert-statement-in-default-function.d.ts +2 -0
  153. package/src/utils/insert-statement-in-default-function.js +23 -0
  154. package/src/utils/remix-config.d.ts +5 -0
  155. package/src/utils/remix-config.js +45 -0
  156. package/src/utils/remix-route-utils.d.ts +13 -0
  157. package/src/utils/remix-route-utils.js +70 -0
  158. package/src/utils/testing-config-utils.d.ts +4 -0
  159. package/src/utils/testing-config-utils.js +79 -0
  160. package/src/utils/upsert-links-function.d.ts +2 -0
  161. package/src/utils/upsert-links-function.js +31 -0
  162. package/src/utils/versions.d.ts +16 -0
  163. package/src/utils/versions.js +28 -0
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const devkit_1 = require("@nx/devkit");
4
+ const artifact_name_and_directory_utils_1 = require("@nx/devkit/src/generators/artifact-name-and-directory-utils");
5
+ const path_1 = require("path");
6
+ const remix_route_utils_1 = require("../../utils/remix-route-utils");
7
+ const action_impl_1 = require("../action/action.impl");
8
+ const loader_impl_1 = require("../loader/loader.impl");
9
+ const meta_impl_1 = require("../meta/meta.impl");
10
+ const style_impl_1 = require("../style/style.impl");
11
+ async function default_1(tree, options) {
12
+ const { artifactName: name, directory, project: projectName, } = await (0, artifact_name_and_directory_utils_1.determineArtifactNameAndDirectoryOptions)(tree, {
13
+ artifactType: 'route',
14
+ callingGenerator: '@nx/remix:route',
15
+ name: options.path.replace(/^\//, '').replace(/\/$/, ''),
16
+ nameAndDirectoryFormat: options.nameAndDirectoryFormat,
17
+ project: options.project,
18
+ });
19
+ const project = (0, devkit_1.readProjectConfiguration)(tree, projectName);
20
+ if (!project)
21
+ throw new Error(`Project does not exist: ${projectName}`);
22
+ if (!options.skipChecks && (0, remix_route_utils_1.checkRoutePathForErrors)(options.path)) {
23
+ throw new Error(`Your route path has an indicator of an un-escaped dollar sign for a route param. If this was intended, include the --skipChecks flag.`);
24
+ }
25
+ const routeFilePath = await (0, remix_route_utils_1.resolveRemixRouteFile)(tree, options.nameAndDirectoryFormat === 'as-provided'
26
+ ? (0, devkit_1.joinPathFragments)(directory, name)
27
+ : options.path, options.nameAndDirectoryFormat === 'as-provided' ? undefined : projectName, '.tsx');
28
+ const nameToUseForComponent = options.nameAndDirectoryFormat === 'as-provided'
29
+ ? name.replace('.tsx', '')
30
+ : options.path.replace(/^\//, '').replace(/\/$/, '').replace('.tsx', '');
31
+ const { className: componentName } = (0, devkit_1.names)(nameToUseForComponent === '.' || nameToUseForComponent === ''
32
+ ? (0, path_1.basename)((0, path_1.dirname)(routeFilePath))
33
+ : nameToUseForComponent);
34
+ if (tree.exists(routeFilePath))
35
+ throw new Error(`Path already exists: ${routeFilePath}`);
36
+ tree.write(routeFilePath, (0, devkit_1.stripIndents) `
37
+
38
+
39
+ export default function ${componentName}() {
40
+ ${options.loader
41
+ ? `
42
+ return (
43
+ <p>
44
+ Message: {data.message}
45
+ </p>
46
+ );
47
+ `
48
+ : `return (<p>${componentName} works!</p>)`}
49
+ }
50
+ `);
51
+ if (options.loader) {
52
+ await (0, loader_impl_1.default)(tree, {
53
+ path: routeFilePath,
54
+ nameAndDirectoryFormat: 'as-provided',
55
+ });
56
+ }
57
+ if (options.meta) {
58
+ await (0, meta_impl_1.default)(tree, {
59
+ path: routeFilePath,
60
+ nameAndDirectoryFormat: 'as-provided',
61
+ });
62
+ }
63
+ if (options.action) {
64
+ await (0, action_impl_1.default)(tree, {
65
+ path: routeFilePath,
66
+ nameAndDirectoryFormat: 'as-provided',
67
+ });
68
+ }
69
+ if (options.style === 'css') {
70
+ await (0, style_impl_1.default)(tree, {
71
+ project: projectName,
72
+ path: routeFilePath,
73
+ nameAndDirectoryFormat: 'as-provided',
74
+ });
75
+ }
76
+ await (0, devkit_1.formatFiles)(tree);
77
+ }
78
+ exports.default = default_1;
@@ -0,0 +1,15 @@
1
+ import { NameAndDirectoryFormat } from '@nx/devkit/src/generators/artifact-name-and-directory-utils';
2
+
3
+ export interface RemixRouteSchema {
4
+ path: string;
5
+ nameAndDirectoryFormat?: NameAndDirectoryFormat;
6
+ style: 'css' | 'none';
7
+ action: boolean;
8
+ meta: boolean;
9
+ loader: boolean;
10
+ skipChecks: boolean;
11
+ /**
12
+ * @deprecated Provide the `path` option instead. The project will be determined from the path provided. It will be removed in Nx v19.
13
+ */
14
+ project?: string;
15
+ }
@@ -0,0 +1,62 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "NxRemixRoute",
4
+ "title": "Create a Route",
5
+ "description": "Generate a route.",
6
+ "type": "object",
7
+ "examples": [
8
+ {
9
+ "command": "g route 'path/to/page'",
10
+ "description": "Generate route at /path/to/page"
11
+ }
12
+ ],
13
+ "properties": {
14
+ "path": {
15
+ "type": "string",
16
+ "description": "The route path or path to the filename of the route. When `--nameAndDirectoryFormat=as-provided`, it will be relative to the current working directory. Otherwise, it will be relative to the workspace root.",
17
+ "$default": {
18
+ "$source": "argv",
19
+ "index": 0
20
+ },
21
+ "x-prompt": "What is the path of the route? (e.g. 'apps/demo/app/routes/foo/bar')"
22
+ },
23
+ "nameAndDirectoryFormat": {
24
+ "description": "Whether to generate the route in the path as provided, relative to the current working directory and ignoring the project (`as-provided`) or generate it using the project and path relative to the workspace root (`derived`).",
25
+ "type": "string",
26
+ "enum": ["as-provided", "derived"]
27
+ },
28
+ "project": {
29
+ "type": "string",
30
+ "description": "The name of the project.",
31
+ "pattern": "^[a-zA-Z].*$",
32
+ "x-deprecated": "Provide the `path` option instead and use the `as-provided` format. The project will be determined from the path provided. It will be removed in Nx v19."
33
+ },
34
+ "style": {
35
+ "type": "string",
36
+ "description": "Generate a stylesheet",
37
+ "enum": ["none", "css"],
38
+ "default": "css"
39
+ },
40
+ "meta": {
41
+ "type": "boolean",
42
+ "description": "Generate a meta function",
43
+ "default": false
44
+ },
45
+ "action": {
46
+ "type": "boolean",
47
+ "description": "Generate an action function",
48
+ "default": false
49
+ },
50
+ "loader": {
51
+ "type": "boolean",
52
+ "description": "Generate a loader function",
53
+ "default": false
54
+ },
55
+ "skipChecks": {
56
+ "type": "boolean",
57
+ "description": "Skip route error detection",
58
+ "default": false
59
+ }
60
+ },
61
+ "required": ["path"]
62
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "NxRemixSetup",
4
+ "title": "",
5
+ "type": "object",
6
+ "description": "Generate initial files required for Remix to work within the workspace.",
7
+ "properties": {
8
+ "packageManager": {
9
+ "type": "string",
10
+ "description": "The package manager to setup for",
11
+ "enum": ["yarn", "npm", "pnpm"]
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,2 @@
1
+ import { GeneratorCallback, Tree } from '@nx/devkit';
2
+ export default function (tree: Tree): Promise<GeneratorCallback>;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const devkit_1 = require("@nx/devkit");
4
+ const js_1 = require("@nx/js");
5
+ async function default_1(tree) {
6
+ const tasks = [];
7
+ const jsInitTask = await (0, js_1.initGenerator)(tree, {
8
+ skipFormat: true,
9
+ });
10
+ tasks.push(jsInitTask);
11
+ // Ignore nested project files
12
+ let ignoreFile = tree.read('.gitignore').toString();
13
+ if (ignoreFile.indexOf('/dist') !== -1) {
14
+ ignoreFile = ignoreFile.replace('/dist', 'dist');
15
+ }
16
+ if (ignoreFile.indexOf('/node_modules') !== -1) {
17
+ ignoreFile = ignoreFile.replace('/node_modules', 'node_modules');
18
+ }
19
+ if (ignoreFile.indexOf('# Remix files') === -1) {
20
+ ignoreFile = `${ignoreFile}
21
+ # Remix files
22
+ apps/**/build
23
+ apps/**/.cache
24
+ `;
25
+ }
26
+ tree.write('.gitignore', ignoreFile);
27
+ (0, devkit_1.updateJson)(tree, `package.json`, (json) => {
28
+ json.type = 'module';
29
+ return json;
30
+ });
31
+ await (0, devkit_1.formatFiles)(tree);
32
+ return (0, devkit_1.runTasksInSerial)(...tasks);
33
+ }
34
+ exports.default = default_1;
@@ -0,0 +1,170 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`setup-tailwind generator should add a js tailwind config to an application correctly 1`] = `
4
+ "import { createGlobPatternsForDependencies } from '@nx/react/tailwind';
5
+ export default {
6
+ content: [
7
+ './app/**/*.{js,jsx,ts,tsx}',
8
+ ...createGlobPatternsForDependencies(__dirname),
9
+ ],
10
+ theme: {
11
+ extend: {},
12
+ },
13
+ plugins: [],
14
+ };
15
+ "
16
+ `;
17
+
18
+ exports[`setup-tailwind generator should add a js tailwind config to an application correctly 2`] = `
19
+ "@tailwind base;
20
+ @tailwind components;
21
+ @tailwind utilities;
22
+ "
23
+ `;
24
+
25
+ exports[`setup-tailwind generator should add a js tailwind config to an application correctly 3`] = `
26
+ "import {
27
+ Links,
28
+ LiveReload,
29
+ Meta,
30
+ Outlet,
31
+ Scripts,
32
+ ScrollRestoration,
33
+ } from '@remix-run/react';
34
+ import twStyles from './tailwind.css';
35
+ export const links = () => [{ rel: 'stylesheet', href: twStyles }];
36
+ export const meta = () => [
37
+ {
38
+ charset: 'utf-8',
39
+ title: 'New Remix App',
40
+ viewport: 'width=device-width,initial-scale=1',
41
+ },
42
+ ];
43
+ export default function App() {
44
+ return (
45
+ <html lang="en">
46
+ <head>
47
+ <Meta />
48
+ <Links />
49
+ </head>
50
+ <body>
51
+ <Outlet />
52
+ <ScrollRestoration />
53
+ <Scripts />
54
+ <LiveReload />
55
+ </body>
56
+ </html>
57
+ );
58
+ }
59
+ "
60
+ `;
61
+
62
+ exports[`setup-tailwind generator should add a js tailwind config to an application correctly 4`] = `
63
+ "import { createWatchPaths } from '@nx/remix';
64
+ import { dirname } from 'path';
65
+ import { fileURLToPath } from 'url';
66
+
67
+ const __dirname = dirname(fileURLToPath(import.meta.url));
68
+
69
+ /**
70
+ * @type {import('@remix-run/dev').AppConfig}
71
+ */
72
+ export default {
73
+ tailwind: true,
74
+ ignoredRouteFiles: ['**/.*'],
75
+ // appDirectory: "app",
76
+ // assetsBuildDirectory: "public/build",
77
+ // serverBuildPath: "build/index.js",
78
+ // publicPath: "/build/",
79
+ watchPaths: () => createWatchPaths(__dirname),
80
+ };
81
+ "
82
+ `;
83
+
84
+ exports[`setup-tailwind generator should add a tailwind config to an application correctly 1`] = `
85
+ "import type { Config } from "tailwindcss";
86
+ import { createGlobPatternsForDependencies } from '@nx/react/tailwind';
87
+
88
+ export default {
89
+ content: [
90
+ "./app/**/*.{js,jsx,ts,tsx}",
91
+ ...createGlobPatternsForDependencies(__dirname)
92
+ ],
93
+ theme: {
94
+ extend: {},
95
+ },
96
+ plugins: [],
97
+ } satisfies Config;
98
+ "
99
+ `;
100
+
101
+ exports[`setup-tailwind generator should add a tailwind config to an application correctly 2`] = `
102
+ "@tailwind base;
103
+ @tailwind components;
104
+ @tailwind utilities;
105
+ "
106
+ `;
107
+
108
+ exports[`setup-tailwind generator should add a tailwind config to an application correctly 3`] = `
109
+ "import type { MetaFunction, LinksFunction } from '@remix-run/node';
110
+ import {
111
+ Links,
112
+ LiveReload,
113
+ Meta,
114
+ Outlet,
115
+ Scripts,
116
+ ScrollRestoration,
117
+ } from '@remix-run/react';
118
+ import twStyles from './tailwind.css';
119
+ export const links: LinksFunction = () => [
120
+ { rel: 'stylesheet', href: twStyles },
121
+ ];
122
+
123
+ export const meta: MetaFunction = () => [
124
+ {
125
+ charset: 'utf-8',
126
+ title: 'New Remix App',
127
+ viewport: 'width=device-width,initial-scale=1',
128
+ },
129
+ ];
130
+
131
+ export default function App() {
132
+ return (
133
+ <html lang="en">
134
+ <head>
135
+ <Meta />
136
+ <Links />
137
+ </head>
138
+ <body>
139
+ <Outlet />
140
+ <ScrollRestoration />
141
+ <Scripts />
142
+ <LiveReload />
143
+ </body>
144
+ </html>
145
+ );
146
+ }
147
+ "
148
+ `;
149
+
150
+ exports[`setup-tailwind generator should add a tailwind config to an application correctly 4`] = `
151
+ "import { createWatchPaths } from '@nx/remix';
152
+ import { dirname } from 'path';
153
+ import { fileURLToPath } from 'url';
154
+
155
+ const __dirname = dirname(fileURLToPath(import.meta.url));
156
+
157
+ /**
158
+ * @type {import('@remix-run/dev').AppConfig}
159
+ */
160
+ export default {
161
+ tailwind: true,
162
+ ignoredRouteFiles: ['**/.*'],
163
+ // appDirectory: "app",
164
+ // assetsBuildDirectory: "public/build",
165
+ // serverBuildPath: "build/index.js",
166
+ // publicPath: "/build/",
167
+ watchPaths: () => createWatchPaths(__dirname),
168
+ };
169
+ "
170
+ `;
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
@@ -0,0 +1,13 @@
1
+ import type { Config } from "tailwindcss";
2
+ import { createGlobPatternsForDependencies } from '@nx/react/tailwind';
3
+
4
+ export default {
5
+ content: [
6
+ "./app/**/*.{js,jsx,ts,tsx}",
7
+ ...createGlobPatternsForDependencies(__dirname)
8
+ ],
9
+ theme: {
10
+ extend: {},
11
+ },
12
+ plugins: [],
13
+ } satisfies Config;
@@ -0,0 +1 @@
1
+ export * from './update-remix-config';
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./update-remix-config"), exports);
@@ -0,0 +1,2 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export declare function updateRemixConfig(tree: Tree, projectRoot: string): void;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateRemixConfig = void 0;
4
+ const tsquery_1 = require("@phenomnomnominal/tsquery");
5
+ const remix_config_1 = require("../../../utils/remix-config");
6
+ function updateRemixConfig(tree, projectRoot) {
7
+ const pathToRemixConfig = (0, remix_config_1.getRemixConfigPathFromProjectRoot)(tree, projectRoot);
8
+ const fileContents = tree.read(pathToRemixConfig, 'utf-8');
9
+ const REMIX_CONFIG_OBJECT_SELECTOR = 'ObjectLiteralExpression';
10
+ const ast = tsquery_1.tsquery.ast(fileContents);
11
+ const nodes = (0, tsquery_1.tsquery)(ast, REMIX_CONFIG_OBJECT_SELECTOR, {
12
+ visitAllChildren: true,
13
+ });
14
+ if (nodes.length === 0) {
15
+ throw new Error(`Remix Config is not valid, unable to update the file.`);
16
+ }
17
+ const configObjectNode = nodes[0];
18
+ const propertyNodes = (0, tsquery_1.tsquery)(configObjectNode, 'PropertyAssignment', {
19
+ visitAllChildren: true,
20
+ });
21
+ for (const propertyNode of propertyNodes) {
22
+ const nodeText = propertyNode.getText();
23
+ if (nodeText.includes('tailwind') && nodeText.includes('true')) {
24
+ return;
25
+ }
26
+ else if (nodeText.includes('tailwind') && nodeText.includes('false')) {
27
+ const updatedFileContents = `${fileContents.slice(0, propertyNode.getStart())}tailwind: true${fileContents.slice(propertyNode.getEnd())}`;
28
+ tree.write(pathToRemixConfig, updatedFileContents);
29
+ return;
30
+ }
31
+ }
32
+ const updatedFileContents = `${fileContents.slice(0, configObjectNode.getStart() + 1)}\ntailwind: true,${fileContents.slice(configObjectNode.getStart() + 1)}`;
33
+ tree.write(pathToRemixConfig, updatedFileContents);
34
+ }
35
+ exports.updateRemixConfig = updateRemixConfig;
@@ -0,0 +1,5 @@
1
+ export interface SetupTailwindSchema {
2
+ project: string;
3
+ js?: boolean;
4
+ skipFormat?: boolean;
5
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "NxRemixTailwind",
4
+ "title": "Add TailwindCSS to a Remix App",
5
+ "description": "Setup tailwindcss for a given project.",
6
+ "type": "object",
7
+ "examples": [
8
+ {
9
+ "command": "g setup-tailwind --project=myapp",
10
+ "description": "Generate a TailwindCSS config for your Remix app"
11
+ }
12
+ ],
13
+ "properties": {
14
+ "project": {
15
+ "type": "string",
16
+ "description": "The name of the project to add tailwind to",
17
+ "$default": {
18
+ "$source": "projectName"
19
+ },
20
+ "x-prompt": "What project would you like to add Tailwind to?",
21
+ "pattern": "^[a-zA-Z].*$"
22
+ },
23
+ "js": {
24
+ "type": "boolean",
25
+ "description": "Generate a JavaScript config file instead of a TypeScript config file",
26
+ "default": false
27
+ },
28
+ "skipFormat": {
29
+ "type": "boolean",
30
+ "description": "Skip formatting files after generator runs",
31
+ "default": false,
32
+ "x-priority": "internal"
33
+ }
34
+ },
35
+ "required": ["project"]
36
+ }
@@ -0,0 +1,3 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ import type { SetupTailwindSchema } from './schema';
3
+ export default function setupTailwind(tree: Tree, options: SetupTailwindSchema): Promise<() => void>;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const devkit_1 = require("@nx/devkit");
4
+ const upsert_links_function_1 = require("../../utils/upsert-links-function");
5
+ const versions_1 = require("../../utils/versions");
6
+ const lib_1 = require("./lib");
7
+ async function setupTailwind(tree, options) {
8
+ const project = (0, devkit_1.readProjectConfiguration)(tree, options.project);
9
+ if (project.projectType !== 'application') {
10
+ throw new Error(`Project "${options.project}" is not an application. Please ensure the project is an application.`);
11
+ }
12
+ (0, lib_1.updateRemixConfig)(tree, project.root);
13
+ (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files'), project.root, {
14
+ tpl: '',
15
+ });
16
+ if (options.js) {
17
+ tree.rename((0, devkit_1.joinPathFragments)(project.root, 'app/root.js'), (0, devkit_1.joinPathFragments)(project.root, 'app/root.tsx'));
18
+ }
19
+ const pathToRoot = (0, devkit_1.joinPathFragments)(project.root, 'app/root.tsx');
20
+ (0, upsert_links_function_1.upsertLinksFunction)(tree, pathToRoot, 'twStyles', './tailwind.css', `{ rel: "stylesheet", href: twStyles }`);
21
+ (0, devkit_1.addDependenciesToPackageJson)(tree, {
22
+ tailwindcss: versions_1.tailwindVersion,
23
+ }, {});
24
+ if (options.js) {
25
+ (0, devkit_1.toJS)(tree);
26
+ }
27
+ if (!options.skipFormat) {
28
+ await (0, devkit_1.formatFiles)(tree);
29
+ }
30
+ return () => {
31
+ (0, devkit_1.installPackagesTask)(tree);
32
+ };
33
+ }
34
+ exports.default = setupTailwind;
@@ -0,0 +1,73 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Storybook Configuration it should create a storybook configuration and use react-vite framework with testing framework jest 1`] = `
4
+ "import type { StorybookConfig } from '@storybook/react-vite';
5
+
6
+ const config: StorybookConfig = {
7
+ stories: ['../src/lib/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
8
+ addons: ['@storybook/addon-essentials', '@storybook/addon-interactions'],
9
+ framework: {
10
+ name: '@storybook/react-vite',
11
+ options: {
12
+ builder: {
13
+ viteConfigPath: 'vite.config.ts',
14
+ },
15
+ },
16
+ },
17
+ };
18
+
19
+ export default config;
20
+
21
+ // To customize your Vite configuration you can use the viteFinal field.
22
+ // Check https://storybook.js.org/docs/react/builders/vite#configuration
23
+ // and https://nx.dev/recipes/storybook/custom-builder-configs
24
+ "
25
+ `;
26
+
27
+ exports[`Storybook Configuration it should create a storybook configuration and use react-vite framework with testing framework none 1`] = `
28
+ "import type { StorybookConfig } from '@storybook/react-vite';
29
+
30
+ const config: StorybookConfig = {
31
+ stories: ['../src/lib/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
32
+ addons: ['@storybook/addon-essentials', '@storybook/addon-interactions'],
33
+ framework: {
34
+ name: '@storybook/react-vite',
35
+ options: {
36
+ builder: {
37
+ viteConfigPath: 'vite.config.ts',
38
+ },
39
+ },
40
+ },
41
+ };
42
+
43
+ export default config;
44
+
45
+ // To customize your Vite configuration you can use the viteFinal field.
46
+ // Check https://storybook.js.org/docs/react/builders/vite#configuration
47
+ // and https://nx.dev/recipes/storybook/custom-builder-configs
48
+ "
49
+ `;
50
+
51
+ exports[`Storybook Configuration it should create a storybook configuration and use react-vite framework with testing framework vitest 1`] = `
52
+ "import type { StorybookConfig } from '@storybook/react-vite';
53
+
54
+ const config: StorybookConfig = {
55
+ stories: ['../src/lib/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
56
+ addons: ['@storybook/addon-essentials', '@storybook/addon-interactions'],
57
+ framework: {
58
+ name: '@storybook/react-vite',
59
+ options: {
60
+ builder: {
61
+ viteConfigPath: 'vite.config.ts',
62
+ },
63
+ },
64
+ },
65
+ };
66
+
67
+ export default config;
68
+
69
+ // To customize your Vite configuration you can use the viteFinal field.
70
+ // Check https://storybook.js.org/docs/react/builders/vite#configuration
71
+ // and https://nx.dev/recipes/storybook/custom-builder-configs
72
+ "
73
+ `;
@@ -0,0 +1,15 @@
1
+ /// <reference types="vitest" />
2
+ import {defineConfig} from 'vite';
3
+ import react from '@vitejs/plugin-react';
4
+ import viteTsConfigPaths from 'vite-tsconfig-paths';
5
+
6
+ export default defineConfig({
7
+ cacheDir: '../../../node_modules/.vite/storybook-generator-test',
8
+
9
+ plugins: [
10
+ react(),
11
+ viteTsConfigPaths({
12
+ root: '../../../',
13
+ }),
14
+ ],
15
+ })
@@ -0,0 +1,16 @@
1
+ import { Linter } from '@nx/eslint';
2
+
3
+ export interface StorybookConfigurationSchema {
4
+ project: string;
5
+ configureCypress: boolean;
6
+ generateStories?: boolean;
7
+ generateCypressSpecs?: boolean;
8
+ js?: boolean;
9
+ tsConfiguration?: boolean;
10
+ linter?: Linter;
11
+ cypressDirectory?: string;
12
+ ignorePaths?: string[];
13
+ configureTestRunner?: boolean;
14
+ configureStaticServe?: boolean;
15
+ addPlugin?: boolean;
16
+ }