create-meridian-app 2.6.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.
@@ -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": "latest",
28
- "@meridianjs/framework": "latest",
29
- "@meridianjs/framework-utils": "latest",
30
- "@meridianjs/types": "latest",
31
- "@meridianjs/auth": "latest",
32
- "@meridianjs/event-bus-local": "latest",
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": "latest" } : {},
46
+ ...vars.dashboard ? { "@meridianjs/admin-dashboard": MERIDIAN_DEP } : {},
35
47
  ...Object.fromEntries(
36
- vars.optionalModules.map((id) => [`@meridianjs/${id}`, "latest"])
48
+ vars.optionalModules.map((id) => [`@meridianjs/${id}`, MERIDIAN_DEP])
37
49
  )
38
50
  },
39
51
  devDependencies: {
40
- "create-meridian-app": "latest",
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 { authenticateJWT } from "@meridianjs/auth"
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: "/admin", middlewares: [authenticateJWT] },
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-SO3S6MDJ.js";
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
- if (args.path === "react/jsx-runtime") {
62
- return {
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 outfile = path.join(os.tmpdir(), `meridian-ext-${Date.now()}.js`);
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
- const buf = fs.readFileSync(outfile);
104
- fs.unlinkSync(outfile);
105
- return buf;
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: { ...process.env, NODE_ENV: process.env.NODE_ENV ?? "development", FORCE_COLOR: "1" }
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 Type-checking project..."));
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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runNew
4
- } from "./chunk-SO3S6MDJ.js";
4
+ } from "./chunk-AR3BATX7.js";
5
5
 
6
6
  // src/index.ts
7
7
  var projectName = process.argv[2];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-meridian-app",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "Create a new Meridian project or manage an existing one",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",