frappe-nextjs 0.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 (98) hide show
  1. package/README.md +90 -0
  2. package/dist/bin/cli.d.ts +3 -0
  3. package/dist/bin/cli.d.ts.map +1 -0
  4. package/dist/bin/cli.js +156 -0
  5. package/dist/bin/cli.js.map +1 -0
  6. package/dist/build/boilerplates.d.ts +12 -0
  7. package/dist/build/boilerplates.d.ts.map +1 -0
  8. package/dist/build/boilerplates.js +261 -0
  9. package/dist/build/boilerplates.js.map +1 -0
  10. package/dist/build/build.d.ts +27 -0
  11. package/dist/build/build.d.ts.map +1 -0
  12. package/dist/build/build.js +172 -0
  13. package/dist/build/build.js.map +1 -0
  14. package/dist/build/context-generator.d.ts +13 -0
  15. package/dist/build/context-generator.d.ts.map +1 -0
  16. package/dist/build/context-generator.js +76 -0
  17. package/dist/build/context-generator.js.map +1 -0
  18. package/dist/build/hooks-patcher.d.ts +11 -0
  19. package/dist/build/hooks-patcher.d.ts.map +1 -0
  20. package/dist/build/hooks-patcher.js +78 -0
  21. package/dist/build/hooks-patcher.js.map +1 -0
  22. package/dist/build/index.d.ts +8 -0
  23. package/dist/build/index.d.ts.map +1 -0
  24. package/dist/build/index.js +33 -0
  25. package/dist/build/index.js.map +1 -0
  26. package/dist/build/init.d.ts +27 -0
  27. package/dist/build/init.d.ts.map +1 -0
  28. package/dist/build/init.js +175 -0
  29. package/dist/build/init.js.map +1 -0
  30. package/dist/build/nginx-generator.d.ts +22 -0
  31. package/dist/build/nginx-generator.d.ts.map +1 -0
  32. package/dist/build/nginx-generator.js +114 -0
  33. package/dist/build/nginx-generator.js.map +1 -0
  34. package/dist/build/supervisor-generator.d.ts +31 -0
  35. package/dist/build/supervisor-generator.d.ts.map +1 -0
  36. package/dist/build/supervisor-generator.js +105 -0
  37. package/dist/build/supervisor-generator.js.map +1 -0
  38. package/dist/client/FrappeClient.d.ts +143 -0
  39. package/dist/client/FrappeClient.d.ts.map +1 -0
  40. package/dist/client/FrappeClient.js +446 -0
  41. package/dist/client/FrappeClient.js.map +1 -0
  42. package/dist/client/index.d.ts +3 -0
  43. package/dist/client/index.d.ts.map +1 -0
  44. package/dist/client/index.js +21 -0
  45. package/dist/client/index.js.map +1 -0
  46. package/dist/client/types.d.ts +140 -0
  47. package/dist/client/types.d.ts.map +1 -0
  48. package/dist/client/types.js +17 -0
  49. package/dist/client/types.js.map +1 -0
  50. package/dist/hooks/FrappeProvider.d.ts +41 -0
  51. package/dist/hooks/FrappeProvider.d.ts.map +1 -0
  52. package/dist/hooks/FrappeProvider.js +48 -0
  53. package/dist/hooks/FrappeProvider.js.map +1 -0
  54. package/dist/hooks/index.d.ts +8 -0
  55. package/dist/hooks/index.d.ts.map +1 -0
  56. package/dist/hooks/index.js +17 -0
  57. package/dist/hooks/index.js.map +1 -0
  58. package/dist/hooks/useFrappeAuth.d.ts +37 -0
  59. package/dist/hooks/useFrappeAuth.d.ts.map +1 -0
  60. package/dist/hooks/useFrappeAuth.js +111 -0
  61. package/dist/hooks/useFrappeAuth.js.map +1 -0
  62. package/dist/hooks/useFrappeCall.d.ts +26 -0
  63. package/dist/hooks/useFrappeCall.d.ts.map +1 -0
  64. package/dist/hooks/useFrappeCall.js +47 -0
  65. package/dist/hooks/useFrappeCall.js.map +1 -0
  66. package/dist/hooks/useFrappeDoc.d.ts +37 -0
  67. package/dist/hooks/useFrappeDoc.d.ts.map +1 -0
  68. package/dist/hooks/useFrappeDoc.js +79 -0
  69. package/dist/hooks/useFrappeDoc.js.map +1 -0
  70. package/dist/hooks/useFrappeDocList.d.ts +37 -0
  71. package/dist/hooks/useFrappeDocList.d.ts.map +1 -0
  72. package/dist/hooks/useFrappeDocList.js +65 -0
  73. package/dist/hooks/useFrappeDocList.js.map +1 -0
  74. package/dist/hooks/useFrappeFileUpload.d.ts +40 -0
  75. package/dist/hooks/useFrappeFileUpload.d.ts.map +1 -0
  76. package/dist/hooks/useFrappeFileUpload.js +68 -0
  77. package/dist/hooks/useFrappeFileUpload.js.map +1 -0
  78. package/dist/index.d.ts +10 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +24 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/ssr/index.d.ts +4 -0
  83. package/dist/ssr/index.d.ts.map +1 -0
  84. package/dist/ssr/index.js +13 -0
  85. package/dist/ssr/index.js.map +1 -0
  86. package/dist/ssr/middleware.d.ts +18 -0
  87. package/dist/ssr/middleware.d.ts.map +1 -0
  88. package/dist/ssr/middleware.js +132 -0
  89. package/dist/ssr/middleware.js.map +1 -0
  90. package/dist/ssr/proxy-config.d.ts +33 -0
  91. package/dist/ssr/proxy-config.d.ts.map +1 -0
  92. package/dist/ssr/proxy-config.js +133 -0
  93. package/dist/ssr/proxy-config.js.map +1 -0
  94. package/dist/ssr/server-client.d.ts +73 -0
  95. package/dist/ssr/server-client.d.ts.map +1 -0
  96. package/dist/ssr/server-client.js +94 -0
  97. package/dist/ssr/server-client.js.map +1 -0
  98. package/package.json +79 -0
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.buildNextJsProject = buildNextJsProject;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const child_process_1 = require("child_process");
40
+ /**
41
+ * Build the Next.js project and deploy it for Frappe.
42
+ *
43
+ * Static mode:
44
+ * 1. Runs `next build` (output: 'export')
45
+ * 2. Copies static files to <app>/public/<spa>/
46
+ * 3. Copies index.html to <app>/www/<spa>.html
47
+ * 4. Injects CSRF token
48
+ *
49
+ * SSR mode:
50
+ * 1. Runs `next build` (output: 'standalone')
51
+ * 2. Copies static assets for nginx to serve
52
+ * 3. Prints setup instructions for supervisor/nginx
53
+ */
54
+ async function buildNextJsProject(options) {
55
+ const { appPath, appName, spaName, mode } = options;
56
+ const spaPath = path.join(appPath, spaName);
57
+ if (!fs.existsSync(spaPath)) {
58
+ console.error(`āŒ SPA directory not found: ${spaPath}`);
59
+ process.exit(1);
60
+ }
61
+ console.log(`\nšŸ”Ø Building Next.js project: ${spaName}`);
62
+ console.log(` Mode: ${mode}`);
63
+ console.log('');
64
+ // Step 1: Run next build
65
+ console.log('šŸ“¦ Running next build...');
66
+ (0, child_process_1.execSync)('npm run build', {
67
+ cwd: spaPath,
68
+ stdio: 'inherit',
69
+ env: { ...process.env, NODE_ENV: 'production' },
70
+ });
71
+ if (mode === 'static') {
72
+ await buildStatic(appPath, appName, spaName, spaPath);
73
+ }
74
+ else {
75
+ await buildSSR(appPath, appName, spaName, spaPath);
76
+ }
77
+ }
78
+ async function buildStatic(appPath, appName, spaName, spaPath) {
79
+ const outDir = path.join(spaPath, 'out');
80
+ const publicDir = path.join(appPath, appName, 'public', spaName);
81
+ const wwwDir = path.join(appPath, appName, 'www');
82
+ if (!fs.existsSync(outDir)) {
83
+ console.error('āŒ Build output not found. Make sure next.config has output: "export"');
84
+ process.exit(1);
85
+ }
86
+ // Step 2: Copy to public directory
87
+ console.log(`\nšŸ“ Copying build output to ${publicDir}...`);
88
+ if (fs.existsSync(publicDir)) {
89
+ fs.rmSync(publicDir, { recursive: true });
90
+ }
91
+ copyDirSync(outDir, publicDir);
92
+ // Step 3: Copy index.html to www
93
+ console.log(`šŸ“„ Copying index.html to ${wwwDir}/${spaName}.html...`);
94
+ const indexHtml = path.join(outDir, 'index.html');
95
+ if (fs.existsSync(indexHtml)) {
96
+ let html = fs.readFileSync(indexHtml, 'utf-8');
97
+ // Inject CSRF token
98
+ html = html.replace('</head>', `<script>
99
+ window.csrf_token = '{{ frappe.session.csrf_token }}';
100
+ </script>
101
+ </head>`);
102
+ // Update asset paths to use Frappe's assets URL
103
+ html = html.replace(/\/_next\//g, `/assets/${appName}/${spaName}/_next/`);
104
+ fs.mkdirSync(wwwDir, { recursive: true });
105
+ fs.writeFileSync(path.join(wwwDir, `${spaName}.html`), html, 'utf-8');
106
+ }
107
+ console.log(`
108
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
109
+ āœ… Static build complete!
110
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
111
+
112
+ Files:
113
+ ${publicDir}/ (static assets)
114
+ ${wwwDir}/${spaName}.html (entry point)
115
+
116
+ Run 'bench build' to include these in Frappe's static assets.
117
+ Then visit: https://<your-site>/${spaName}
118
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
119
+ `);
120
+ }
121
+ async function buildSSR(appPath, appName, spaName, spaPath) {
122
+ const standalonePath = path.join(spaPath, '.next', 'standalone');
123
+ if (!fs.existsSync(standalonePath)) {
124
+ console.error('āŒ Standalone build not found. Make sure next.config has output: "standalone"');
125
+ process.exit(1);
126
+ }
127
+ // Copy static assets for nginx to serve
128
+ const staticSrc = path.join(spaPath, '.next', 'static');
129
+ const staticDest = path.join(standalonePath, '.next', 'static');
130
+ if (fs.existsSync(staticSrc) && !fs.existsSync(staticDest)) {
131
+ console.log('šŸ“ Copying static assets into standalone...');
132
+ copyDirSync(staticSrc, staticDest);
133
+ }
134
+ // Copy public assets
135
+ const publicSrc = path.join(spaPath, 'public');
136
+ const publicDest = path.join(standalonePath, 'public');
137
+ if (fs.existsSync(publicSrc) && !fs.existsSync(publicDest)) {
138
+ console.log('šŸ“ Copying public assets into standalone...');
139
+ copyDirSync(publicSrc, publicDest);
140
+ }
141
+ console.log(`
142
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
143
+ āœ… SSR build complete!
144
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
145
+
146
+ Standalone server: ${standalonePath}/server.js
147
+
148
+ To run manually:
149
+ PORT=3100 HOSTNAME=127.0.0.1 node ${standalonePath}/server.js
150
+
151
+ For production, run:
152
+ frappe-nextjs setup-ssr --app ${appName} --name ${spaName}
153
+
154
+ This will generate supervisor and nginx configs.
155
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
156
+ `);
157
+ }
158
+ // ─── Helpers ──────────────────────────────────────────────────────
159
+ function copyDirSync(src, dest) {
160
+ fs.mkdirSync(dest, { recursive: true });
161
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
162
+ const srcPath = path.join(src, entry.name);
163
+ const destPath = path.join(dest, entry.name);
164
+ if (entry.isDirectory()) {
165
+ copyDirSync(srcPath, destPath);
166
+ }
167
+ else {
168
+ fs.copyFileSync(srcPath, destPath);
169
+ }
170
+ }
171
+ }
172
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/build/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Generate the Frappe www context files that allow Frappe to serve the SPA.
3
+ *
4
+ * Creates:
5
+ * - <app>/<app>/www/<spaName>.py → Python context (CSRF token, boot data)
6
+ * - <app>/<app>/www/<spaName>.html → HTML template entry point
7
+ *
8
+ * @param appPath - Path to the Frappe app root
9
+ * @param appName - The Python package name
10
+ * @param spaName - SPA name / route prefix
11
+ */
12
+ export declare function generateContextFiles(appPath: string, appName: string, spaName: string): void;
13
+ //# sourceMappingURL=context-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-generator.d.ts","sourceRoot":"","sources":["../../src/build/context-generator.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,IAAI,CAyBN"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateContextFiles = generateContextFiles;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const boilerplates_1 = require("./boilerplates");
40
+ /**
41
+ * Generate the Frappe www context files that allow Frappe to serve the SPA.
42
+ *
43
+ * Creates:
44
+ * - <app>/<app>/www/<spaName>.py → Python context (CSRF token, boot data)
45
+ * - <app>/<app>/www/<spaName>.html → HTML template entry point
46
+ *
47
+ * @param appPath - Path to the Frappe app root
48
+ * @param appName - The Python package name
49
+ * @param spaName - SPA name / route prefix
50
+ */
51
+ function generateContextFiles(appPath, appName, spaName) {
52
+ const wwwDir = path.join(appPath, appName, 'www');
53
+ // Create www directory if it doesn't exist
54
+ if (!fs.existsSync(wwwDir)) {
55
+ fs.mkdirSync(wwwDir, { recursive: true });
56
+ }
57
+ // Generate Python context file
58
+ const pyPath = path.join(wwwDir, `${spaName}.py`);
59
+ if (!fs.existsSync(pyPath)) {
60
+ fs.writeFileSync(pyPath, (0, boilerplates_1.getContextPyBoilerplate)(spaName), 'utf-8');
61
+ console.log(`āœ… Created ${pyPath}`);
62
+ }
63
+ else {
64
+ console.log(`ā­ ${pyPath} already exists, skipping`);
65
+ }
66
+ // Generate HTML entry point
67
+ const htmlPath = path.join(wwwDir, `${spaName}.html`);
68
+ if (!fs.existsSync(htmlPath)) {
69
+ fs.writeFileSync(htmlPath, (0, boilerplates_1.getHtmlEntryBoilerplate)(spaName), 'utf-8');
70
+ console.log(`āœ… Created ${htmlPath}`);
71
+ }
72
+ else {
73
+ console.log(`ā­ ${htmlPath} already exists, skipping`);
74
+ }
75
+ }
76
+ //# sourceMappingURL=context-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-generator.js","sourceRoot":"","sources":["../../src/build/context-generator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,oDA6BC;AA/CD,uCAAyB;AACzB,2CAA6B;AAC7B,iDAGwB;AAExB;;;;;;;;;;GAUG;AACH,SAAgB,oBAAoB,CAClC,OAAe,EACf,OAAe,EACf,OAAe;IAEf,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAElD,2CAA2C;IAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,+BAA+B;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,KAAK,CAAC,CAAC;IAClD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,IAAA,sCAAuB,EAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,2BAA2B,CAAC,CAAC;IACtD,CAAC;IAED,4BAA4B;IAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,OAAO,CAAC,CAAC;IACtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAA,sCAAuB,EAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,2BAA2B,CAAC,CAAC;IACxD,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Patch a Frappe app's hooks.py to add website_route_rules for the SPA.
3
+ *
4
+ * This follows the same pattern as doppio's add_routing_rule_to_hooks utility.
5
+ *
6
+ * @param appPath - Absolute path to the Frappe app root (e.g. /path/to/bench/apps/myapp)
7
+ * @param appName - The Python package name of the app (often same as directory name)
8
+ * @param spaName - The SPA name / route prefix (e.g. 'dashboard')
9
+ */
10
+ export declare function patchHooks(appPath: string, appName: string, spaName: string): void;
11
+ //# sourceMappingURL=hooks-patcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-patcher.d.ts","sourceRoot":"","sources":["../../src/build/hooks-patcher.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAmClF"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.patchHooks = patchHooks;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ /**
40
+ * Patch a Frappe app's hooks.py to add website_route_rules for the SPA.
41
+ *
42
+ * This follows the same pattern as doppio's add_routing_rule_to_hooks utility.
43
+ *
44
+ * @param appPath - Absolute path to the Frappe app root (e.g. /path/to/bench/apps/myapp)
45
+ * @param appName - The Python package name of the app (often same as directory name)
46
+ * @param spaName - The SPA name / route prefix (e.g. 'dashboard')
47
+ */
48
+ function patchHooks(appPath, appName, spaName) {
49
+ const hooksPath = path.join(appPath, appName, 'hooks.py');
50
+ if (!fs.existsSync(hooksPath)) {
51
+ console.error(`hooks.py not found at ${hooksPath}`);
52
+ return;
53
+ }
54
+ let hooks = fs.readFileSync(hooksPath, 'utf-8');
55
+ const rule = `{"from_route": "/${spaName}/<path:app_path>", "to_route": "${spaName}"}`;
56
+ // Check if rule already exists
57
+ if (hooks.includes(`/${spaName}/<path:app_path>`)) {
58
+ console.log(`Route rule for '${spaName}' already exists in hooks.py`);
59
+ return;
60
+ }
61
+ // Try to append to existing website_route_rules
62
+ const pattern = /website_route_rules\s*=\s*\[([^\]]*)\]/;
63
+ const match = pattern.exec(hooks);
64
+ if (match) {
65
+ // Append to existing list
66
+ const existingRules = match[1].trim();
67
+ const separator = existingRules ? ',\n\t' : '\n\t';
68
+ const newRules = `website_route_rules = [${existingRules}${separator}${rule},\n]`;
69
+ hooks = hooks.replace(pattern, newRules);
70
+ }
71
+ else {
72
+ // Add new website_route_rules list
73
+ hooks += `\nwebsite_route_rules = [\n\t${rule},\n]\n`;
74
+ }
75
+ fs.writeFileSync(hooksPath, hooks, 'utf-8');
76
+ console.log(`āœ… Added website_route_rules for '/${spaName}' in hooks.py`);
77
+ }
78
+ //# sourceMappingURL=hooks-patcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-patcher.js","sourceRoot":"","sources":["../../src/build/hooks-patcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,gCAmCC;AA/CD,uCAAyB;AACzB,2CAA6B;AAE7B;;;;;;;;GAQG;AACH,SAAgB,UAAU,CAAC,OAAe,EAAE,OAAe,EAAE,OAAe;IAC1E,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAE1D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,IAAI,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAG,oBAAoB,OAAO,mCAAmC,OAAO,IAAI,CAAC;IAEvF,+BAA+B;IAC/B,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,OAAO,kBAAkB,CAAC,EAAE,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,mBAAmB,OAAO,8BAA8B,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,gDAAgD;IAChD,MAAM,OAAO,GAAG,wCAAwC,CAAC;IACzD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAElC,IAAI,KAAK,EAAE,CAAC;QACV,0BAA0B;QAC1B,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACnD,MAAM,QAAQ,GAAG,0BAA0B,aAAa,GAAG,SAAS,GAAG,IAAI,MAAM,CAAC;QAClF,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC;SAAM,CAAC;QACN,mCAAmC;QACnC,KAAK,IAAI,gCAAgC,IAAI,QAAQ,CAAC;IACxD,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,qCAAqC,OAAO,eAAe,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { initNextJsProject } from './init';
2
+ export { buildNextJsProject } from './build';
3
+ export { patchHooks } from './hooks-patcher';
4
+ export { generateContextFiles } from './context-generator';
5
+ export { generateSupervisorConfig, getSupervisorInstructions } from './supervisor-generator';
6
+ export { generateNginxConfig, getNginxInstructions } from './nginx-generator';
7
+ export * from './boilerplates';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/build/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.getNginxInstructions = exports.generateNginxConfig = exports.getSupervisorInstructions = exports.generateSupervisorConfig = exports.generateContextFiles = exports.patchHooks = exports.buildNextJsProject = exports.initNextJsProject = void 0;
18
+ var init_1 = require("./init");
19
+ Object.defineProperty(exports, "initNextJsProject", { enumerable: true, get: function () { return init_1.initNextJsProject; } });
20
+ var build_1 = require("./build");
21
+ Object.defineProperty(exports, "buildNextJsProject", { enumerable: true, get: function () { return build_1.buildNextJsProject; } });
22
+ var hooks_patcher_1 = require("./hooks-patcher");
23
+ Object.defineProperty(exports, "patchHooks", { enumerable: true, get: function () { return hooks_patcher_1.patchHooks; } });
24
+ var context_generator_1 = require("./context-generator");
25
+ Object.defineProperty(exports, "generateContextFiles", { enumerable: true, get: function () { return context_generator_1.generateContextFiles; } });
26
+ var supervisor_generator_1 = require("./supervisor-generator");
27
+ Object.defineProperty(exports, "generateSupervisorConfig", { enumerable: true, get: function () { return supervisor_generator_1.generateSupervisorConfig; } });
28
+ Object.defineProperty(exports, "getSupervisorInstructions", { enumerable: true, get: function () { return supervisor_generator_1.getSupervisorInstructions; } });
29
+ var nginx_generator_1 = require("./nginx-generator");
30
+ Object.defineProperty(exports, "generateNginxConfig", { enumerable: true, get: function () { return nginx_generator_1.generateNginxConfig; } });
31
+ Object.defineProperty(exports, "getNginxInstructions", { enumerable: true, get: function () { return nginx_generator_1.getNginxInstructions; } });
32
+ __exportStar(require("./boilerplates"), exports);
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/build/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,+BAA2C;AAAlC,yGAAA,iBAAiB,OAAA;AAC1B,iCAA6C;AAApC,2GAAA,kBAAkB,OAAA;AAC3B,iDAA6C;AAApC,2GAAA,UAAU,OAAA;AACnB,yDAA2D;AAAlD,yHAAA,oBAAoB,OAAA;AAC7B,+DAA6F;AAApF,gIAAA,wBAAwB,OAAA;AAAE,iIAAA,yBAAyB,OAAA;AAC5D,qDAA8E;AAArE,sHAAA,mBAAmB,OAAA;AAAE,uHAAA,oBAAoB,OAAA;AAClD,iDAA+B"}
@@ -0,0 +1,27 @@
1
+ interface InitOptions {
2
+ /** Absolute path to the Frappe app root (e.g. /path/to/bench/apps/myapp) */
3
+ appPath: string;
4
+ /** Python package name of the app (usually same as directory name) */
5
+ appName: string;
6
+ /** Name for the SPA / route prefix (e.g. 'dashboard') */
7
+ spaName: string;
8
+ /** Deployment mode */
9
+ mode: 'ssr' | 'static';
10
+ /** Frappe webserver port (default: 8000) */
11
+ frappePort?: number;
12
+ }
13
+ /**
14
+ * Scaffold a new Next.js project inside a Frappe app.
15
+ *
16
+ * This creates a Next.js App Router project pre-configured to work with Frappe,
17
+ * including:
18
+ * - Next.js project with TypeScript
19
+ * - FrappeProvider setup in layout
20
+ * - proxy.ts for API proxying and auth (Next.js 16+)
21
+ * - Server client for SSR
22
+ * - Frappe www context files
23
+ * - hooks.py routing rules
24
+ */
25
+ export declare function initNextJsProject(options: InitOptions): Promise<void>;
26
+ export {};
27
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/build/init.ts"],"names":[],"mappings":"AAgBA,UAAU,WAAW;IACnB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC;IACvB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA8K3E"}
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.initNextJsProject = initNextJsProject;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const child_process_1 = require("child_process");
40
+ const proxy_config_1 = require("../ssr/proxy-config");
41
+ const middleware_1 = require("../ssr/middleware");
42
+ const hooks_patcher_1 = require("./hooks-patcher");
43
+ const context_generator_1 = require("./context-generator");
44
+ const boilerplates_1 = require("./boilerplates");
45
+ /**
46
+ * Scaffold a new Next.js project inside a Frappe app.
47
+ *
48
+ * This creates a Next.js App Router project pre-configured to work with Frappe,
49
+ * including:
50
+ * - Next.js project with TypeScript
51
+ * - FrappeProvider setup in layout
52
+ * - proxy.ts for API proxying and auth (Next.js 16+)
53
+ * - Server client for SSR
54
+ * - Frappe www context files
55
+ * - hooks.py routing rules
56
+ */
57
+ async function initNextJsProject(options) {
58
+ const { appPath, appName, spaName, mode, frappePort = 8000, } = options;
59
+ const spaPath = path.join(appPath, spaName);
60
+ // Validate
61
+ if (spaName === appName) {
62
+ console.error('āŒ SPA name must not be the same as the app name.');
63
+ process.exit(1);
64
+ }
65
+ if (fs.existsSync(spaPath)) {
66
+ console.error(`āŒ Directory '${spaPath}' already exists.`);
67
+ process.exit(1);
68
+ }
69
+ console.log(`\nšŸš€ Initializing Next.js project: ${spaName}`);
70
+ console.log(` Mode: ${mode}`);
71
+ console.log(` App: ${appName} (${appPath})`);
72
+ console.log('');
73
+ // Step 1: Create Next.js project
74
+ console.log('šŸ“¦ Creating Next.js project...');
75
+ (0, child_process_1.execSync)(`npx -y create-next-app@latest ${spaName} --typescript --eslint --app --src-dir --no-tailwind --import-alias "@/*" --use-npm`, {
76
+ cwd: appPath,
77
+ stdio: 'inherit',
78
+ });
79
+ // Step 2: Install frappe-nextjs and SWR
80
+ console.log('\nšŸ“¦ Installing frappe-nextjs dependencies...');
81
+ try {
82
+ (0, child_process_1.execSync)('npm install frappe-nextjs swr', {
83
+ cwd: spaPath,
84
+ stdio: 'inherit',
85
+ });
86
+ }
87
+ catch {
88
+ // Package not on npm — pack and install from local path (development mode)
89
+ console.log('āš ļø frappe-nextjs not found on npm, installing from local package...');
90
+ const localPkgPath = path.resolve(__dirname, '..', '..');
91
+ // Use npm pack to create a tarball (avoids symlinks that Turbopack can't resolve)
92
+ const packOutput = (0, child_process_1.execSync)('npm pack --pack-destination /tmp', {
93
+ cwd: localPkgPath,
94
+ encoding: 'utf-8',
95
+ }).trim();
96
+ const tarball = `/tmp/${packOutput}`;
97
+ (0, child_process_1.execSync)(`npm install ${tarball} swr`, {
98
+ cwd: spaPath,
99
+ stdio: 'inherit',
100
+ });
101
+ }
102
+ // Step 3: Write next.config.mjs
103
+ console.log('\nāš™ļø Configuring Next.js...');
104
+ const nextConfigPath = path.join(spaPath, 'next.config.mjs');
105
+ // Remove any existing next.config files
106
+ for (const f of ['next.config.mjs', 'next.config.js', 'next.config.ts']) {
107
+ const p = path.join(spaPath, f);
108
+ if (fs.existsSync(p))
109
+ fs.unlinkSync(p);
110
+ }
111
+ fs.writeFileSync(nextConfigPath, (0, proxy_config_1.generateNextConfig)(spaName, mode, frappePort), 'utf-8');
112
+ // Step 4: Write app files
113
+ console.log('šŸ“ Creating app files...');
114
+ const appDir = path.join(spaPath, 'src', 'app');
115
+ // layout.tsx
116
+ fs.writeFileSync(path.join(appDir, 'layout.tsx'), (0, boilerplates_1.getLayoutBoilerplate)(spaName), 'utf-8');
117
+ // providers.tsx
118
+ fs.writeFileSync(path.join(appDir, 'providers.tsx'), (0, boilerplates_1.getProvidersBoilerplate)(), 'utf-8');
119
+ // page.tsx
120
+ fs.writeFileSync(path.join(appDir, 'page.tsx'), (0, boilerplates_1.getHomePageBoilerplate)(spaName), 'utf-8');
121
+ // globals.css
122
+ fs.writeFileSync(path.join(appDir, 'globals.css'), (0, boilerplates_1.getGlobalsCssBoilerplate)(), 'utf-8');
123
+ // Step 5: Create lib/frappe.ts (server client)
124
+ const libDir = path.join(spaPath, 'src', 'lib');
125
+ fs.mkdirSync(libDir, { recursive: true });
126
+ fs.writeFileSync(path.join(libDir, 'frappe.ts'), (0, boilerplates_1.getServerClientBoilerplate)(), 'utf-8');
127
+ // Step 6: Create proxy.ts (Next.js 16+ API proxy + auth guard)
128
+ console.log('šŸ” Adding proxy.ts (API proxy + auth guard)...');
129
+ fs.writeFileSync(path.join(spaPath, 'src', 'proxy.ts'), (0, middleware_1.generateProxy)(spaName, frappePort), 'utf-8');
130
+ // Step 7: Create .env.local
131
+ fs.writeFileSync(path.join(spaPath, '.env.local'), (0, boilerplates_1.getEnvBoilerplate)(frappePort), 'utf-8');
132
+ // Step 8: Generate Frappe www context files
133
+ console.log('šŸ Creating Frappe context files...');
134
+ (0, context_generator_1.generateContextFiles)(appPath, appName, spaName);
135
+ // Step 9: Patch hooks.py
136
+ console.log('šŸ”§ Patching hooks.py...');
137
+ (0, hooks_patcher_1.patchHooks)(appPath, appName, spaName);
138
+ // Step 10: Update app's package.json with scripts
139
+ const appPkgPath = path.join(appPath, 'package.json');
140
+ let appPkg = {};
141
+ if (fs.existsSync(appPkgPath)) {
142
+ appPkg = JSON.parse(fs.readFileSync(appPkgPath, 'utf-8'));
143
+ }
144
+ else {
145
+ appPkg = { name: appName, version: '1.0.0', private: true, scripts: {} };
146
+ }
147
+ appPkg.scripts = appPkg.scripts || {};
148
+ appPkg.scripts[`dev:${spaName}`] = `cd ${spaName} && npm run dev`;
149
+ appPkg.scripts[`build:${spaName}`] = `cd ${spaName} && npm run build`;
150
+ fs.writeFileSync(appPkgPath, JSON.stringify(appPkg, null, 2), 'utf-8');
151
+ // Done!
152
+ console.log(`
153
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
154
+ āœ… Next.js project '${spaName}' created!
155
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
156
+
157
+ Start development:
158
+ cd ${spaPath}
159
+ npm run dev
160
+
161
+ Your Next.js dev server will run on port 3000 (default).
162
+ Frappe dev server should be running on port ${frappePort}.
163
+
164
+ API calls from the browser are proxied to Frappe automatically.
165
+
166
+ For SSR, set your API credentials in .env.local:
167
+ FRAPPE_API_KEY=<your-api-key>
168
+ FRAPPE_API_SECRET=<your-api-secret>
169
+
170
+ Generate API keys in Frappe:
171
+ User → Settings → API Access → Generate Keys
172
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
173
+ `);
174
+ }
175
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/build/init.ts"],"names":[],"mappings":"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"}