@adonisjs/inertia 1.0.0-9 → 1.1.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.
Files changed (46) hide show
  1. package/README.md +3 -3
  2. package/build/app.css.stub +1 -1
  3. package/build/{chunk-CXICUKHN.js → chunk-QKSM72AR.js} +59 -23
  4. package/build/config.stub +18 -3
  5. package/build/index.d.ts +7 -3
  6. package/build/index.js +140 -38
  7. package/build/providers/inertia_provider.d.ts +15 -1
  8. package/build/providers/inertia_provider.js +13 -2
  9. package/build/react/app.tsx.stub +19 -6
  10. package/build/react/errors/not_found.tsx.stub +14 -0
  11. package/build/react/errors/server_error.tsx.stub +14 -0
  12. package/build/react/home.tsx.stub +2 -2
  13. package/build/react/root.edge.stub +2 -2
  14. package/build/react/ssr.tsx.stub +17 -0
  15. package/build/react/tsconfig.json.stub +5 -15
  16. package/build/solid/app.tsx.stub +19 -5
  17. package/build/solid/errors/not_found.tsx.stub +14 -0
  18. package/build/solid/errors/server_error.tsx.stub +14 -0
  19. package/build/solid/home.tsx.stub +2 -5
  20. package/build/solid/root.edge.stub +2 -2
  21. package/build/solid/ssr.tsx.stub +19 -0
  22. package/build/solid/tsconfig.json.stub +6 -16
  23. package/build/src/helpers.d.ts +12 -0
  24. package/build/src/helpers.js +14 -0
  25. package/build/src/inertia_middleware.d.ts +5 -51
  26. package/build/src/inertia_middleware.js +1 -1
  27. package/build/src/plugins/japa/api_client.d.ts +3 -1
  28. package/build/src/plugins/vite.d.ts +1 -1
  29. package/build/src/plugins/vite.js +5 -2
  30. package/build/src/types.d.ts +5 -96
  31. package/build/svelte/app.ts.stub +33 -0
  32. package/build/svelte/errors/not_found.svelte.stub +10 -0
  33. package/build/svelte/errors/server_error.svelte.stub +14 -0
  34. package/build/svelte/home.svelte.stub +19 -0
  35. package/build/svelte/root.edge.stub +21 -0
  36. package/build/svelte/ssr.ts.stub +15 -0
  37. package/build/svelte/tsconfig.json.stub +14 -0
  38. package/build/types-fb05P61I.d.ts +203 -0
  39. package/build/vue/app.ts.stub +18 -4
  40. package/build/vue/errors/not_found.vue.stub +10 -0
  41. package/build/vue/errors/server_error.vue.stub +14 -0
  42. package/build/vue/home.vue.stub +4 -4
  43. package/build/vue/root.edge.stub +2 -2
  44. package/build/vue/ssr.ts.stub +22 -0
  45. package/build/vue/tsconfig.json.stub +5 -15
  46. package/package.json +52 -42
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  Official [Inertia.js](https://inertiajs.com/) adapter for AdonisJS.
9
9
 
10
10
  ## Official Documentation
11
- The documentation is available on the [AdonisJS website](https://docs.adonisjs.com/guides/inertia/introduction).
11
+ The documentation is available on the [AdonisJS website](https://docs.adonisjs.com/guides/inertia/).
12
12
 
13
13
  ## Contributing
14
14
  One of the primary goals of AdonisJS is to have a vibrant community of users and contributors who believes in the principles of the framework.
@@ -21,8 +21,8 @@ In order to ensure that the AdonisJS community is welcoming to all, please revie
21
21
  ## License
22
22
  AdonisJS Lucid is open-sourced software licensed under the [MIT license](LICENSE.md).
23
23
 
24
- [gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/inertia/test.yml?style=for-the-badge
25
- [gh-workflow-url]: https://github.com/adonisjs/inertia/actions/workflows/test.yml "Github action"
24
+ [gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/inertia/checks.yml?style=for-the-badge
25
+ [gh-workflow-url]: https://github.com/adonisjs/inertia/actions/workflows/checks.yml "Github action"
26
26
 
27
27
  [npm-image]: https://img.shields.io/npm/v/@adonisjs/inertia/latest.svg?style=for-the-badge&logo=npm
28
28
  [npm-url]: https://www.npmjs.com/package/@adonisjs/inertia/v/latest "npm"
@@ -1,5 +1,5 @@
1
1
  {{{
2
- exports({ to: app.makePath('resources/css/app.css') })
2
+ exports({ to: app.makePath('inertia/css/app.css') })
3
3
  }}}
4
4
  @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500&display=swap');
5
5
 
@@ -1,13 +1,42 @@
1
+ // src/server_renderer.ts
2
+ import { pathToFileURL } from "node:url";
3
+ var ServerRenderer = class {
4
+ constructor(config, vite) {
5
+ this.config = config;
6
+ this.vite = vite;
7
+ }
8
+ /**
9
+ * Render the page on the server
10
+ *
11
+ * On development, we use the Vite Runtime API
12
+ * On production, we just import and use the SSR bundle generated by Vite
13
+ */
14
+ async render(pageObject) {
15
+ let render;
16
+ const devServer = this.vite?.getDevServer();
17
+ if (devServer) {
18
+ const runtime = await this.vite.createRuntime();
19
+ render = await runtime.executeEntrypoint(this.config.ssr.entrypoint);
20
+ } else {
21
+ render = await import(pathToFileURL(this.config.ssr.bundle).href);
22
+ }
23
+ const result = await render.default(pageObject);
24
+ return { head: result.head, body: result.body };
25
+ }
26
+ };
27
+
1
28
  // src/inertia.ts
2
29
  var kLazySymbol = Symbol("lazy");
3
30
  var Inertia = class {
4
- constructor(ctx, config, viteRuntime) {
31
+ constructor(ctx, config, vite) {
5
32
  this.ctx = ctx;
6
33
  this.config = config;
7
- this.viteRuntime = viteRuntime;
34
+ this.vite = vite;
8
35
  this.#sharedData = config.sharedData;
36
+ this.#serverRenderer = new ServerRenderer(config, vite);
9
37
  }
10
38
  #sharedData = {};
39
+ #serverRenderer;
11
40
  /**
12
41
  * Check if a value is a lazy prop
13
42
  */
@@ -62,30 +91,38 @@ var Inertia = class {
62
91
  };
63
92
  }
64
93
  /**
65
- * If the page should be rendered on the server
94
+ * If the page should be rendered on the server or not
95
+ *
96
+ * The ssr.pages config can be a list of pages or a function that returns a boolean
66
97
  */
67
- #shouldRenderOnServer(component) {
98
+ async #shouldRenderOnServer(component) {
68
99
  const isSsrEnabled = this.config.ssr.enabled;
69
- const isSsrEnabledForPage = this.config.ssr.pages ? this.config.ssr.pages.includes(component) : true;
70
- return isSsrEnabled && isSsrEnabledForPage;
100
+ if (!isSsrEnabled)
101
+ return false;
102
+ let isSsrEnabledForPage = false;
103
+ if (typeof this.config.ssr.pages === "function") {
104
+ isSsrEnabledForPage = await this.config.ssr.pages(this.ctx, component);
105
+ } else if (this.config.ssr.pages) {
106
+ isSsrEnabledForPage = this.config.ssr.pages?.includes(component);
107
+ } else {
108
+ isSsrEnabledForPage = true;
109
+ }
110
+ return isSsrEnabledForPage;
111
+ }
112
+ /**
113
+ * Resolve the root view
114
+ */
115
+ #resolveRootView() {
116
+ return typeof this.config.rootView === "function" ? this.config.rootView(this.ctx) : this.config.rootView;
71
117
  }
72
118
  /**
73
119
  * Render the page on the server
74
- *
75
- * On development, we use the Vite Runtime API
76
- * On production, we just import and use the SSR bundle generated by Vite
77
120
  */
78
121
  async #renderOnServer(pageObject, viewProps) {
79
- let render;
80
- if (this.viteRuntime) {
81
- render = await this.viteRuntime.executeEntrypoint(this.config.ssr.entrypoint);
82
- } else {
83
- render = await import(this.config.ssr.bundle);
84
- }
85
- const result = await render.default(pageObject);
86
- return this.ctx.view.render(this.config.rootView, {
122
+ const { head, body } = await this.#serverRenderer.render(pageObject);
123
+ return this.ctx.view.render(this.#resolveRootView(), {
87
124
  ...viewProps,
88
- page: { ssrHead: result.head, ssrBody: result.body }
125
+ page: { ssrHead: head, ssrBody: body, ...pageObject }
89
126
  });
90
127
  }
91
128
  /**
@@ -102,10 +139,10 @@ var Inertia = class {
102
139
  const pageObject = await this.#buildPageObject(component, pageProps);
103
140
  const isInertiaRequest = !!this.ctx.request.header("x-inertia");
104
141
  if (!isInertiaRequest) {
105
- const shouldRenderOnServer = this.#shouldRenderOnServer(component);
142
+ const shouldRenderOnServer = await this.#shouldRenderOnServer(component);
106
143
  if (shouldRenderOnServer)
107
144
  return this.#renderOnServer(pageObject, viewProps);
108
- return this.ctx.view.render(this.config.rootView, { ...viewProps, page: pageObject });
145
+ return this.ctx.view.render(this.#resolveRootView(), { ...viewProps, page: pageObject });
109
146
  }
110
147
  this.ctx.response.header("x-inertia", "true");
111
148
  return pageObject;
@@ -137,12 +174,11 @@ var Inertia = class {
137
174
  var InertiaMiddleware = class {
138
175
  constructor(config, vite) {
139
176
  this.config = config;
140
- this.#runtime = vite?.getRuntime();
177
+ this.vite = vite;
141
178
  }
142
- #runtime;
143
179
  async handle(ctx, next) {
144
180
  const { response, request } = ctx;
145
- ctx.inertia = new Inertia(ctx, this.config, this.#runtime);
181
+ ctx.inertia = new Inertia(ctx, this.config, this.vite);
146
182
  await next();
147
183
  const isInertiaRequest = !!request.header("x-inertia");
148
184
  if (!isInertiaRequest)
package/build/config.stub CHANGED
@@ -2,17 +2,32 @@
2
2
  exports({ to: app.configPath('inertia.ts') })
3
3
  }}}
4
4
  import { defineConfig } from '@adonisjs/inertia'
5
+ import type { InferSharedProps } from '@adonisjs/inertia/types'
5
6
 
6
- export default defineConfig({
7
+ const inertiaConfig = defineConfig({
7
8
  /**
8
9
  * Path to the Edge view that will be used as the root view for Inertia responses
9
10
  */
10
- rootView: 'root',
11
+ rootView: 'inertia_layout',
11
12
 
12
13
  /**
13
14
  * Data that should be shared with all rendered pages
14
15
  */
15
16
  sharedData: {
16
- errors: (ctx) => ctx.session.flashMessages.get('errors'),
17
+ errors: (ctx) => ctx.session?.flashMessages.get('errors'),
17
18
  },
19
+
20
+ /**
21
+ * Options for the server-side rendering
22
+ */
23
+ ssr: {
24
+ enabled: {{ ssr }},
25
+ entrypoint: '{{ ssrEntrypoint }}'
26
+ }
18
27
  })
28
+
29
+ export default inertiaConfig
30
+
31
+ declare module '@adonisjs/inertia/types' {
32
+ export interface SharedProps extends InferSharedProps<typeof inertiaConfig> {}
33
+ }
package/build/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import Configure from '@adonisjs/core/commands/configure';
2
2
  import { ConfigProvider } from '@adonisjs/core/types';
3
- import { InertiaConfig, ResolvedConfig } from './src/types.js';
3
+ import { S as SharedData, I as InertiaConfig, R as ResolvedConfig } from './types-fb05P61I.js';
4
4
  import '@adonisjs/core/http';
5
+ import '@tuyau/utils/types';
6
+ import '@adonisjs/vite';
5
7
 
6
8
  /**
7
9
  * Configures the package
@@ -11,6 +13,8 @@ declare function configure(command: Configure): Promise<void>;
11
13
  /**
12
14
  * Define the Inertia configuration
13
15
  */
14
- declare function defineConfig(config: InertiaConfig): ConfigProvider<ResolvedConfig>;
16
+ declare function defineConfig<T extends SharedData>(config: InertiaConfig<T>): ConfigProvider<ResolvedConfig<T>>;
15
17
 
16
- export { configure, defineConfig };
18
+ declare const stubsRoot: string;
19
+
20
+ export { configure, defineConfig, stubsRoot };
package/build/index.js CHANGED
@@ -1,11 +1,14 @@
1
+ // configure.ts
2
+ import string from "@poppinss/utils/string";
3
+
1
4
  // stubs/main.ts
2
5
  import { getDirname } from "@poppinss/utils";
3
6
  var stubsRoot = getDirname(import.meta.url);
4
7
 
5
8
  // configure.ts
6
- var ADAPTERS = ["Vue 3", "React", "Svelte", "Solid"];
9
+ var ADAPTERS = ["vue", "react", "svelte", "solid"];
7
10
  var ADAPTERS_INFO = {
8
- "Vue 3": {
11
+ vue: {
9
12
  stubFolder: "vue",
10
13
  appExtension: "ts",
11
14
  componentsExtension: "vue",
@@ -14,12 +17,14 @@ var ADAPTERS_INFO = {
14
17
  { name: "vue", isDevDependency: false },
15
18
  { name: "@vitejs/plugin-vue", isDevDependency: true }
16
19
  ],
20
+ ssrDependencies: [{ name: "@vue/server-renderer", isDevDependency: false }],
17
21
  viteRegister: {
18
22
  pluginCall: "vue()",
19
23
  importDeclarations: [{ isNamed: false, module: "@vitejs/plugin-vue", identifier: "vue" }]
20
- }
24
+ },
25
+ ssrEntrypoint: "inertia/app/ssr.ts"
21
26
  },
22
- "React": {
27
+ react: {
23
28
  stubFolder: "react",
24
29
  appExtension: "tsx",
25
30
  componentsExtension: "tsx",
@@ -34,9 +39,10 @@ var ADAPTERS_INFO = {
34
39
  viteRegister: {
35
40
  pluginCall: "react()",
36
41
  importDeclarations: [{ isNamed: false, module: "@vitejs/plugin-react", identifier: "react" }]
37
- }
42
+ },
43
+ ssrEntrypoint: "inertia/app/ssr.tsx"
38
44
  },
39
- "Svelte": {
45
+ svelte: {
40
46
  stubFolder: "svelte",
41
47
  appExtension: "ts",
42
48
  componentsExtension: "svelte",
@@ -47,12 +53,14 @@ var ADAPTERS_INFO = {
47
53
  ],
48
54
  viteRegister: {
49
55
  pluginCall: "svelte()",
56
+ ssrPluginCall: "svelte({ compilerOptions: { hydratable: true } })",
50
57
  importDeclarations: [
51
- { isNamed: false, module: "@sveltejs/vite-plugin-svelte", identifier: "svelte" }
58
+ { isNamed: true, module: "@sveltejs/vite-plugin-svelte", identifier: "svelte" }
52
59
  ]
53
- }
60
+ },
61
+ ssrEntrypoint: "inertia/app/ssr.ts"
54
62
  },
55
- "Solid": {
63
+ solid: {
56
64
  stubFolder: "solid",
57
65
  appExtension: "tsx",
58
66
  componentsExtension: "tsx",
@@ -64,8 +72,10 @@ var ADAPTERS_INFO = {
64
72
  ],
65
73
  viteRegister: {
66
74
  pluginCall: "solid()",
75
+ ssrPluginCall: "solid({ ssr: true })",
67
76
  importDeclarations: [{ isNamed: false, module: "vite-plugin-solid", identifier: "solid" }]
68
- }
77
+ },
78
+ ssrEntrypoint: "inertia/app/ssr.tsx"
69
79
  }
70
80
  };
71
81
  async function defineExampleRoute(command, codemods) {
@@ -74,17 +84,10 @@ async function defineExampleRoute(command, codemods) {
74
84
  if (!routesFile) {
75
85
  return command.logger.warning("Unable to find the routes file");
76
86
  }
77
- const isAlreadyDefined = routesFile.getText().includes("/inertia");
78
- if (isAlreadyDefined) {
79
- command.logger.warning("/inertia route is already defined. Skipping");
80
- return;
81
- }
82
87
  const action = command.logger.action("update start/routes.ts file");
83
88
  try {
84
89
  routesFile?.addStatements((writer) => {
85
- writer.writeLine(
86
- `router.get('/inertia', ({ inertia }) => inertia.render('home', { version: 6 }))`
87
- );
90
+ writer.writeLine(`router.on('/').renderInertia('home', { version: 6 })`);
88
91
  });
89
92
  await tsMorph?.save();
90
93
  action.succeeded();
@@ -94,47 +97,90 @@ async function defineExampleRoute(command, codemods) {
94
97
  }
95
98
  }
96
99
  async function configure(command) {
97
- const adapter = await command.prompt.choice(
98
- "Select the Inertia adapter you want to use",
99
- ADAPTERS,
100
- { name: "adapter" }
101
- );
100
+ let adapter = command.parsedFlags.adapter;
101
+ let ssr = command.parsedFlags.ssr;
102
+ let shouldInstallPackages = command.parsedFlags.install;
103
+ let shouldSkipExampleRoute = command.parsedFlags["skip-example-route"];
104
+ if (adapter === void 0) {
105
+ adapter = await command.prompt.choice(
106
+ "Select the Inertia adapter you want to use",
107
+ ADAPTERS.map((adapterName) => string.capitalCase(adapterName)),
108
+ { name: "adapter", result: (value) => value.toLowerCase() }
109
+ );
110
+ }
111
+ if (ssr === void 0) {
112
+ ssr = await command.prompt.confirm("Do you want to use server-side rendering?", {
113
+ name: "ssr"
114
+ });
115
+ }
116
+ if (adapter in ADAPTERS_INFO === false) {
117
+ command.logger.error(
118
+ `The selected adapter "${adapter}" is invalid. Select one from: ${string.sentence(
119
+ Object.keys(ADAPTERS_INFO)
120
+ )}`
121
+ );
122
+ command.exitCode = 1;
123
+ return;
124
+ }
102
125
  const adapterInfo = ADAPTERS_INFO[adapter];
103
126
  const codemods = await command.createCodemods();
104
127
  await codemods.updateRcFile((rcFile) => {
105
128
  rcFile.addProvider("@adonisjs/inertia/inertia_provider");
106
129
  });
107
- await codemods.registerMiddleware("router", [
130
+ await codemods.registerMiddleware("server", [
108
131
  { path: "@adonisjs/inertia/inertia_middleware", position: "after" }
109
132
  ]);
110
133
  const appExt = adapterInfo.appExtension;
111
134
  const stubFolder = adapterInfo.stubFolder;
112
135
  const compExt = adapterInfo.componentsExtension;
113
- await codemods.makeUsingStub(stubsRoot, "config.stub", {});
136
+ await codemods.makeUsingStub(stubsRoot, "config.stub", {
137
+ ssr,
138
+ ssrEntrypoint: adapterInfo.ssrEntrypoint
139
+ });
114
140
  await codemods.makeUsingStub(stubsRoot, `app.css.stub`, {});
115
141
  await codemods.makeUsingStub(stubsRoot, `${stubFolder}/root.edge.stub`, {});
116
142
  await codemods.makeUsingStub(stubsRoot, `${stubFolder}/tsconfig.json.stub`, {});
117
- await codemods.makeUsingStub(stubsRoot, `${stubFolder}/app.${appExt}.stub`, {});
143
+ await codemods.makeUsingStub(stubsRoot, `${stubFolder}/app.${appExt}.stub`, { ssr });
118
144
  await codemods.makeUsingStub(stubsRoot, `${stubFolder}/home.${compExt}.stub`, {});
145
+ await codemods.makeUsingStub(stubsRoot, `${stubFolder}/errors/not_found.${compExt}.stub`, {});
146
+ await codemods.makeUsingStub(stubsRoot, `${stubFolder}/errors/server_error.${compExt}.stub`, {});
147
+ if (ssr) {
148
+ await codemods.makeUsingStub(stubsRoot, `${stubFolder}/ssr.${appExt}.stub`, {});
149
+ }
150
+ const inertiaPluginCall = ssr ? `inertia({ ssr: { enabled: true, entrypoint: 'inertia/app/ssr.${appExt}' } })` : `inertia({ ssr: { enabled: false } })`;
151
+ await codemods.registerVitePlugin(inertiaPluginCall, [
152
+ { isNamed: false, module: "@adonisjs/inertia/client", identifier: "inertia" }
153
+ ]);
119
154
  await codemods.registerVitePlugin(
120
- adapterInfo.viteRegister.pluginCall,
155
+ ssr && adapterInfo.viteRegister.ssrPluginCall ? adapterInfo.viteRegister.ssrPluginCall : adapterInfo.viteRegister.pluginCall,
121
156
  adapterInfo.viteRegister.importDeclarations
122
157
  );
123
- defineExampleRoute(command, codemods);
158
+ const adonisjsPluginCall = `adonisjs({ entrypoints: ['inertia/app/app.${appExt}'], reload: ['resources/views/**/*.edge'] })`;
159
+ await codemods.registerVitePlugin(adonisjsPluginCall, [
160
+ { isNamed: false, module: "@adonisjs/vite/client", identifier: "adonisjs" }
161
+ ]);
162
+ if (shouldSkipExampleRoute !== true) {
163
+ await defineExampleRoute(command, codemods);
164
+ }
124
165
  const pkgToInstall = adapterInfo.dependencies;
125
- const shouldInstallPackages = await command.prompt.confirm(
126
- `Do you want to install dependencies ${pkgToInstall.map((pkg) => pkg.name).join(", ")}?`,
127
- { name: "install" }
128
- );
166
+ if (ssr && adapterInfo.ssrDependencies) {
167
+ pkgToInstall.push(...adapterInfo.ssrDependencies);
168
+ }
169
+ if (shouldInstallPackages === void 0) {
170
+ shouldInstallPackages = await command.prompt.confirm(
171
+ `Do you want to install dependencies ${pkgToInstall.map((pkg) => pkg.name).join(", ")}?`,
172
+ { name: "install" }
173
+ );
174
+ }
129
175
  if (shouldInstallPackages) {
130
176
  await codemods.installPackages(pkgToInstall);
131
177
  } else {
132
178
  await codemods.listPackagesToInstall(pkgToInstall);
133
179
  }
134
- command.logger.success("Inertia configured");
135
180
  }
136
181
 
137
182
  // src/define_config.ts
183
+ import { slash } from "@poppinss/utils";
138
184
  import { configProvider } from "@adonisjs/core";
139
185
 
140
186
  // src/version_cache.ts
@@ -185,25 +231,81 @@ var VersionCache = class {
185
231
  }
186
232
  };
187
233
 
234
+ // src/files_detector.ts
235
+ import { locatePath } from "locate-path";
236
+ var FilesDetector = class {
237
+ constructor(app) {
238
+ this.app = app;
239
+ }
240
+ /**
241
+ * Try to locate the entrypoint file based
242
+ * on the conventional locations
243
+ */
244
+ async detectEntrypoint(defaultPath) {
245
+ const possiblesLocations = [
246
+ "./inertia/app/app.ts",
247
+ "./inertia/app/app.tsx",
248
+ "./resources/app.ts",
249
+ "./resources/app.tsx",
250
+ "./resources/app.jsx",
251
+ "./resources/app.js",
252
+ "./inertia/app/app.jsx"
253
+ ];
254
+ const path = await locatePath(possiblesLocations, { cwd: this.app.appRoot });
255
+ return this.app.makePath(path || defaultPath);
256
+ }
257
+ /**
258
+ * Try to locate the SSR entrypoint file based
259
+ * on the conventional locations
260
+ */
261
+ async detectSsrEntrypoint(defaultPath) {
262
+ const possiblesLocations = [
263
+ "./inertia/app/ssr.ts",
264
+ "./inertia/app/ssr.tsx",
265
+ "./resources/ssr.ts",
266
+ "./resources/ssr.tsx",
267
+ "./resources/ssr.jsx",
268
+ "./resources/ssr.js",
269
+ "./inertia/app/ssr.jsx"
270
+ ];
271
+ const path = await locatePath(possiblesLocations, { cwd: this.app.appRoot });
272
+ return this.app.makePath(path || defaultPath);
273
+ }
274
+ /**
275
+ * Try to locate the SSR bundle file based
276
+ * on the conventional locations
277
+ */
278
+ async detectSsrBundle(defaultPath) {
279
+ const possiblesLocations = ["./ssr/ssr.js", "./ssr/ssr.mjs"];
280
+ const path = await locatePath(possiblesLocations, { cwd: this.app.appRoot });
281
+ return this.app.makePath(path || defaultPath);
282
+ }
283
+ };
284
+
188
285
  // src/define_config.ts
189
286
  function defineConfig(config) {
190
287
  return configProvider.create(async (app) => {
288
+ const detector = new FilesDetector(app);
191
289
  const versionCache = new VersionCache(app.appRoot, config.assetsVersion);
192
290
  await versionCache.computeVersion();
193
291
  return {
194
- rootView: config.rootView ?? "root",
195
- sharedData: config.sharedData || {},
196
292
  versionCache,
293
+ rootView: config.rootView ?? "inertia_layout",
294
+ sharedData: config.sharedData || {},
295
+ entrypoint: slash(
296
+ config.entrypoint ?? await detector.detectEntrypoint("inertia/app/app.ts")
297
+ ),
197
298
  ssr: {
198
299
  enabled: config.ssr?.enabled ?? false,
199
300
  pages: config.ssr?.pages,
200
- entrypoint: config.ssr?.entrypoint ?? app.makePath("resources/ssr.ts"),
201
- bundle: config.ssr?.bundle ?? app.makePath("ssr/ssr.js")
301
+ entrypoint: config.ssr?.entrypoint ?? await detector.detectSsrEntrypoint("inertia/app/ssr.ts"),
302
+ bundle: config.ssr?.bundle ?? await detector.detectSsrBundle("ssr/ssr.js")
202
303
  }
203
304
  };
204
305
  });
205
306
  }
206
307
  export {
207
308
  configure,
208
- defineConfig
309
+ defineConfig,
310
+ stubsRoot
209
311
  };
@@ -1,5 +1,15 @@
1
+ import { Route } from '@adonisjs/core/http';
1
2
  import { ApplicationService } from '@adonisjs/core/types';
2
3
 
4
+ declare module '@adonisjs/core/http' {
5
+ interface BriskRoute {
6
+ /**
7
+ * Render an inertia page without defining an
8
+ * explicit route handler
9
+ */
10
+ renderInertia(component: string, props?: Record<string, any>, viewProps?: Record<string, any>): Route;
11
+ }
12
+ }
3
13
  /**
4
14
  * Inertia provider
5
15
  */
@@ -11,9 +21,13 @@ declare class InertiaProvider {
11
21
  */
12
22
  protected registerEdgePlugin(): Promise<void>;
13
23
  /**
14
- * Register Inertia bindings
24
+ * Register inertia middleware
15
25
  */
16
26
  register(): Promise<void>;
27
+ /**
28
+ * Register edge plugin and brisk route macro
29
+ */
30
+ boot(): Promise<void>;
17
31
  }
18
32
 
19
33
  export { InertiaProvider as default };
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  InertiaMiddleware
3
- } from "../chunk-CXICUKHN.js";
3
+ } from "../chunk-QKSM72AR.js";
4
4
 
5
5
  // providers/inertia_provider.ts
6
6
  import { configProvider } from "@adonisjs/core";
7
7
  import { RuntimeException } from "@poppinss/utils";
8
+ import { BriskRoute } from "@adonisjs/core/http";
8
9
  var InertiaProvider = class {
9
10
  constructor(app) {
10
11
  this.app = app;
@@ -20,7 +21,7 @@ var InertiaProvider = class {
20
21
  edgeExports.default.use(edgePluginInertia());
21
22
  }
22
23
  /**
23
- * Register Inertia bindings
24
+ * Register inertia middleware
24
25
  */
25
26
  async register() {
26
27
  this.app.container.singleton(InertiaMiddleware, async () => {
@@ -34,7 +35,17 @@ var InertiaProvider = class {
34
35
  }
35
36
  return new InertiaMiddleware(config, vite);
36
37
  });
38
+ }
39
+ /**
40
+ * Register edge plugin and brisk route macro
41
+ */
42
+ async boot() {
37
43
  await this.registerEdgePlugin();
44
+ BriskRoute.macro("renderInertia", function(template, props, viewProps) {
45
+ return this.setHandler(({ inertia }) => {
46
+ return inertia.render(template, props, viewProps);
47
+ });
48
+ });
38
49
  }
39
50
  };
40
51
  export {
@@ -1,10 +1,18 @@
1
1
  {{{
2
- exports({ to: app.makePath('resources/app.tsx') })
2
+ exports({ to: app.makePath('inertia/app/app.tsx') })
3
3
  }}}
4
- import './css/app.css';
4
+ /// <reference path="../../adonisrc.ts" />
5
+ /// <reference path="../../config/inertia.ts" />
5
6
 
7
+ import '../css/app.css';
8
+
9
+ {{#if ssr}}
10
+ import { hydrateRoot } from 'react-dom/client'
11
+ {{#else}}
6
12
  import { createRoot } from 'react-dom/client';
13
+ {{/if}}
7
14
  import { createInertiaApp } from '@inertiajs/react';
15
+ import { resolvePageComponent } from '@adonisjs/inertia/helpers'
8
16
 
9
17
  const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS'
10
18
 
@@ -14,12 +22,17 @@ createInertiaApp({
14
22
  title: (title) => {{ '`${title} - ${appName}`' }},
15
23
 
16
24
  resolve: (name) => {
17
- const pages = import.meta.glob('./pages/**/*.tsx', { eager: true })
18
- {{ 'return pages[`./pages/${name}.tsx`]' }}
25
+ return resolvePageComponent(
26
+ {{ '`../pages/${name}.tsx`' }},
27
+ import.meta.glob('../pages/**/*.tsx'),
28
+ )
19
29
  },
20
30
 
21
31
  setup({ el, App, props }) {
22
- const root = createRoot(el);
23
- root.render(<App {...props} />);
32
+ {{#if ssr}}
33
+ hydrateRoot(el, <App {...props} />)
34
+ {{#else}}
35
+ createRoot(el).render(<App {...props} />);
36
+ {{/if}}
24
37
  },
25
38
  });
@@ -0,0 +1,14 @@
1
+ {{{
2
+ exports({ to: app.makePath('inertia/pages/errors/not_found.tsx') })
3
+ }}}
4
+ export default function NotFound() {
5
+ return (
6
+ <>
7
+ <div className="container">
8
+ <div className="title">Page not found</div>
9
+
10
+ <span>This page does not exist.</span>
11
+ </div>
12
+ </>
13
+ )
14
+ }
@@ -0,0 +1,14 @@
1
+ {{{
2
+ exports({ to: app.makePath('inertia/pages/errors/server_error.tsx') })
3
+ }}}
4
+ export default function ServerError(props: { error: any }) {
5
+ return (
6
+ <>
7
+ <div className="container">
8
+ <div className="title">Server Error</div>
9
+
10
+ <span>{props.error.message}</span>
11
+ </div>
12
+ </>
13
+ )
14
+ }
@@ -1,5 +1,5 @@
1
1
  {{{
2
- exports({ to: app.makePath('resources/pages/home.tsx') })
2
+ exports({ to: app.makePath('inertia/pages/home.tsx') })
3
3
  }}}
4
4
  import { Head } from '@inertiajs/react'
5
5
 
@@ -13,7 +13,7 @@ export default function Home(props: { version: number }) {
13
13
 
14
14
  <span>
15
15
  Learn more about AdonisJS and Inertia.js by visiting the{' '}
16
- <a href="https://docs.adonisjs.com/inertia">AdonisJS documentation</a>.
16
+ <a href="https://docs.adonisjs.com/guides/inertia">AdonisJS documentation</a>.
17
17
  </span>
18
18
  </div>
19
19
  </>