create-meridian-app 2.5.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-SO3S6MDJ.js → chunk-AR3BATX7.js} +41 -12
- package/dist/cli.js +27 -37
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -7,6 +7,17 @@ import prompts from "prompts";
|
|
|
7
7
|
import { execa as execa2 } from "execa";
|
|
8
8
|
|
|
9
9
|
// src/templates/index.ts
|
|
10
|
+
import { createRequire } from "module";
|
|
11
|
+
function meridianDepRange() {
|
|
12
|
+
try {
|
|
13
|
+
const require2 = createRequire(import.meta.url);
|
|
14
|
+
const version = require2("../../package.json").version;
|
|
15
|
+
return `^${version}`;
|
|
16
|
+
} catch {
|
|
17
|
+
return "^2.6.0";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
var MERIDIAN_DEP = meridianDepRange();
|
|
10
21
|
function renderPackageJson(vars) {
|
|
11
22
|
return JSON.stringify(
|
|
12
23
|
{
|
|
@@ -24,20 +35,21 @@ function renderPackageJson(vars) {
|
|
|
24
35
|
...vars.seedDemo ? { "seed:demo": "node --import tsx/esm src/scripts/seed-demo.ts" } : {}
|
|
25
36
|
},
|
|
26
37
|
dependencies: {
|
|
27
|
-
"@meridianjs/meridian":
|
|
28
|
-
"@meridianjs/framework":
|
|
29
|
-
"@meridianjs/framework-utils":
|
|
30
|
-
"@meridianjs/types":
|
|
31
|
-
"@meridianjs/auth":
|
|
32
|
-
"@meridianjs/event-bus-local":
|
|
38
|
+
"@meridianjs/meridian": MERIDIAN_DEP,
|
|
39
|
+
"@meridianjs/framework": MERIDIAN_DEP,
|
|
40
|
+
"@meridianjs/framework-utils": MERIDIAN_DEP,
|
|
41
|
+
"@meridianjs/types": MERIDIAN_DEP,
|
|
42
|
+
"@meridianjs/auth": MERIDIAN_DEP,
|
|
43
|
+
"@meridianjs/event-bus-local": MERIDIAN_DEP,
|
|
44
|
+
"@meridianjs/plugin-mcp": MERIDIAN_DEP,
|
|
33
45
|
"dotenv": "^16.0.0",
|
|
34
|
-
...vars.dashboard ? { "@meridianjs/admin-dashboard":
|
|
46
|
+
...vars.dashboard ? { "@meridianjs/admin-dashboard": MERIDIAN_DEP } : {},
|
|
35
47
|
...Object.fromEntries(
|
|
36
|
-
vars.optionalModules.map((id) => [`@meridianjs/${id}`,
|
|
48
|
+
vars.optionalModules.map((id) => [`@meridianjs/${id}`, MERIDIAN_DEP])
|
|
37
49
|
)
|
|
38
50
|
},
|
|
39
51
|
devDependencies: {
|
|
40
|
-
"create-meridian-app":
|
|
52
|
+
"create-meridian-app": MERIDIAN_DEP,
|
|
41
53
|
typescript: "^5.4.0",
|
|
42
54
|
tsx: "^4.0.0",
|
|
43
55
|
"@types/node": "^22.0.0",
|
|
@@ -149,6 +161,9 @@ ${optBlocks}` : ""}
|
|
|
149
161
|
],
|
|
150
162
|
plugins: [
|
|
151
163
|
{ resolve: "@meridianjs/meridian" },
|
|
164
|
+
// MCP server at /mcp \u2014 connect Claude, Cursor, and other LLM clients
|
|
165
|
+
// using personal access tokens (created at /admin/api-tokens)
|
|
166
|
+
{ resolve: "@meridianjs/plugin-mcp" },
|
|
152
167
|
],
|
|
153
168
|
})
|
|
154
169
|
`;
|
|
@@ -186,11 +201,25 @@ process.on("SIGINT", async () => {
|
|
|
186
201
|
`;
|
|
187
202
|
}
|
|
188
203
|
function renderMiddlewares() {
|
|
189
|
-
return `import {
|
|
190
|
-
|
|
204
|
+
return `import { authenticate } from "@meridianjs/auth"
|
|
205
|
+
import { authRateLimit, oauthRateLimit, apiRateLimit } from "@meridianjs/framework"
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Route-level middleware configuration.
|
|
209
|
+
*
|
|
210
|
+
* /auth/login, /auth/register \u2014 strict rate limit (brute-force protection)
|
|
211
|
+
* /auth/google \u2014 looser limit (a full OAuth flow = 3 requests)
|
|
212
|
+
* /admin/* \u2014 rate-limited + JWT or personal access token required
|
|
213
|
+
*/
|
|
191
214
|
export default {
|
|
192
215
|
routes: [
|
|
193
|
-
{ matcher: "/
|
|
216
|
+
{ matcher: "/auth/login", middlewares: [authRateLimit] },
|
|
217
|
+
{ matcher: "/auth/register", middlewares: [authRateLimit] },
|
|
218
|
+
{ matcher: "/auth/forgot-password", middlewares: [authRateLimit] },
|
|
219
|
+
{ matcher: "/auth/reset-password", middlewares: [authRateLimit] },
|
|
220
|
+
{ matcher: "/auth/google", middlewares: [oauthRateLimit] },
|
|
221
|
+
{ matcher: "/auth/invite", middlewares: [authRateLimit] },
|
|
222
|
+
{ matcher: "/admin", middlewares: [apiRateLimit, authenticate] },
|
|
194
223
|
],
|
|
195
224
|
}
|
|
196
225
|
`;
|
package/dist/cli.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
toKebabCase,
|
|
15
15
|
toPascalCase,
|
|
16
16
|
writeFile
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-AR3BATX7.js";
|
|
18
18
|
|
|
19
19
|
// src/cli.ts
|
|
20
20
|
import { Command } from "commander";
|
|
@@ -50,38 +50,23 @@ var MIME_TYPES = {
|
|
|
50
50
|
".woff2": "font/woff2"
|
|
51
51
|
};
|
|
52
52
|
function makeReactWindowPlugin() {
|
|
53
|
+
const globalFor = {
|
|
54
|
+
"react": "window.__React",
|
|
55
|
+
"react/jsx-runtime": "window.__ReactJsxRuntime",
|
|
56
|
+
"react/jsx-dev-runtime": "window.__ReactJsxRuntime",
|
|
57
|
+
"react-dom": "window.__ReactDOM",
|
|
58
|
+
"react-dom/client": "window.__ReactDOMClient"
|
|
59
|
+
};
|
|
53
60
|
return {
|
|
54
61
|
name: "react-window",
|
|
55
62
|
setup(build2) {
|
|
56
|
-
build2.onResolve({ filter: /^react(\/.*)?$/ }, (args) => ({
|
|
63
|
+
build2.onResolve({ filter: /^react(-dom)?(\/.*)?$/ }, (args) => ({
|
|
57
64
|
path: args.path,
|
|
58
65
|
namespace: "react-window"
|
|
59
66
|
}));
|
|
60
67
|
build2.onLoad({ filter: /.*/, namespace: "react-window" }, (args) => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
contents: `
|
|
64
|
-
const { jsx, jsxs, Fragment } = window.__ReactJsxRuntime;
|
|
65
|
-
export { jsx, jsxs, Fragment };
|
|
66
|
-
`,
|
|
67
|
-
loader: "js"
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
return {
|
|
71
|
-
contents: `
|
|
72
|
-
const R = window.__React;
|
|
73
|
-
export default R;
|
|
74
|
-
export const {
|
|
75
|
-
createElement, createContext, cloneElement, isValidElement,
|
|
76
|
-
useState, useEffect, useContext, useReducer, useCallback, useMemo,
|
|
77
|
-
useRef, useImperativeHandle, useLayoutEffect, useDebugValue, useId,
|
|
78
|
-
useDeferredValue, useTransition, startTransition,
|
|
79
|
-
memo, forwardRef, lazy, Suspense, StrictMode, Fragment,
|
|
80
|
-
Component, PureComponent, Children, createRef,
|
|
81
|
-
} = R;
|
|
82
|
-
`,
|
|
83
|
-
loader: "js"
|
|
84
|
-
};
|
|
68
|
+
const target = globalFor[args.path] ?? "window.__React";
|
|
69
|
+
return { contents: `module.exports = ${target};`, loader: "js" };
|
|
85
70
|
});
|
|
86
71
|
}
|
|
87
72
|
};
|
|
@@ -89,7 +74,8 @@ function makeReactWindowPlugin() {
|
|
|
89
74
|
async function buildAdminExtensions(rootDir) {
|
|
90
75
|
const entryPoint = path.join(rootDir, "src", "admin", "widgets", "index.tsx");
|
|
91
76
|
if (!existsSync(entryPoint)) return null;
|
|
92
|
-
const
|
|
77
|
+
const outDir = fs.mkdtempSync(path.join(os.tmpdir(), "meridian-ext-"));
|
|
78
|
+
const outfile = path.join(outDir, "bundle.js");
|
|
93
79
|
try {
|
|
94
80
|
await esbuild.build({
|
|
95
81
|
entryPoints: [entryPoint],
|
|
@@ -100,12 +86,9 @@ async function buildAdminExtensions(rootDir) {
|
|
|
100
86
|
plugins: [makeReactWindowPlugin()],
|
|
101
87
|
logLevel: "silent"
|
|
102
88
|
});
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
} catch (err) {
|
|
107
|
-
if (existsSync(outfile)) fs.unlinkSync(outfile);
|
|
108
|
-
throw err;
|
|
89
|
+
return fs.readFileSync(outfile);
|
|
90
|
+
} finally {
|
|
91
|
+
fs.rmSync(outDir, { recursive: true, force: true });
|
|
109
92
|
}
|
|
110
93
|
}
|
|
111
94
|
function startDashboardServer(distDir, port, apiPort, apiHost = "localhost", adminExtensionsBuf = null, apiUrlOverride, branding, projectDir) {
|
|
@@ -285,7 +268,14 @@ async function runDev() {
|
|
|
285
268
|
{
|
|
286
269
|
cwd: rootDir,
|
|
287
270
|
stdio: "inherit",
|
|
288
|
-
env: {
|
|
271
|
+
env: {
|
|
272
|
+
...process.env,
|
|
273
|
+
NODE_ENV: process.env.NODE_ENV ?? "development",
|
|
274
|
+
// Auto-sync schema in dev (additive/safe). Production must use
|
|
275
|
+
// migrations — sync is off unless MERIDIAN_DB_SYNC is set.
|
|
276
|
+
MERIDIAN_DB_SYNC: process.env.MERIDIAN_DB_SYNC ?? "1",
|
|
277
|
+
FORCE_COLOR: "1"
|
|
278
|
+
}
|
|
289
279
|
}
|
|
290
280
|
);
|
|
291
281
|
const shutdown = (signal) => {
|
|
@@ -296,8 +286,8 @@ async function runDev() {
|
|
|
296
286
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
297
287
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
298
288
|
await apiProc.catch((err) => {
|
|
289
|
+
dashServer?.close();
|
|
299
290
|
if (err.signal === "SIGINT" || err.signal === "SIGTERM") {
|
|
300
|
-
dashServer?.close();
|
|
301
291
|
process.exit(0);
|
|
302
292
|
}
|
|
303
293
|
throw err;
|
|
@@ -386,7 +376,7 @@ async function runBuild() {
|
|
|
386
376
|
console.error(chalk4.red(" \u2716 Could not find meridian.config.ts. Are you inside a Meridian project?"));
|
|
387
377
|
process.exit(1);
|
|
388
378
|
}
|
|
389
|
-
console.log(chalk4.dim(" \u2192
|
|
379
|
+
console.log(chalk4.dim(" \u2192 Validating project (type-check; Meridian runs .ts directly via tsx)..."));
|
|
390
380
|
console.log();
|
|
391
381
|
const result = await execa3("npx", ["tsc", "--noEmit"], {
|
|
392
382
|
cwd: rootDir,
|
|
@@ -398,7 +388,7 @@ async function runBuild() {
|
|
|
398
388
|
process.exit(result.exitCode ?? 1);
|
|
399
389
|
}
|
|
400
390
|
console.log();
|
|
401
|
-
console.log(chalk4.green(" \u2713 Type check passed"));
|
|
391
|
+
console.log(chalk4.green(" \u2713 Type check passed \u2014 project is ready to run with `meridian start`"));
|
|
402
392
|
}
|
|
403
393
|
|
|
404
394
|
// src/commands/db-migrate.ts
|
package/dist/index.js
CHANGED