create-lacspace-app 2.12.0 → 2.13.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/index.js CHANGED
@@ -7468,6 +7468,7 @@ var backendPkgJson = (ctx) => {
7468
7468
  "@lacspace/id": "^1.1.0",
7469
7469
  "@lacspace/rate-limit": "^1.2.0",
7470
7470
  "@lacspace/cache": "^1.1.0",
7471
+ "@lacspace/logger": "^1.0.0",
7471
7472
  ...featureDeps,
7472
7473
  [`${scope(ctx)}/types`]: "*"
7473
7474
  },
@@ -7577,21 +7578,54 @@ var backendIndex = (ctx) => `import "./load-env.js"; // MUST be first: fills pro
7577
7578
  import { env } from "./env.js";
7578
7579
  import { connectDb } from "./db.js";
7579
7580
  import { createApp } from "./app.js";
7581
+ import { log } from "./logger.js";
7580
7582
 
7581
7583
  // how this works: connect to MongoDB, build the Express app, then listen.
7582
7584
  async function main(): Promise<void> {
7583
7585
  await connectDb(env.MONGODB_URI);
7584
7586
  const app = createApp();
7585
7587
  app.listen(env.PORT, () => {
7586
- console.log(\`\u{1F680} ${ctx.name} API ready on http://localhost:\${env.PORT}\`);
7588
+ log.info("${ctx.name} API ready", { url: \`http://localhost:\${env.PORT}\` });
7587
7589
  });
7588
7590
  }
7589
7591
 
7590
7592
  main().catch((err) => {
7591
- console.error("Failed to start the API:", err);
7593
+ log.fatal("Failed to start the API", { err });
7592
7594
  process.exit(1);
7593
7595
  });
7594
7596
  `;
7597
+ var backendLogger = () => `import { createLogger, jsonConsole, prettyConsole } from "@lacspace/logger";
7598
+ import type { Request, Response, NextFunction } from "express";
7599
+ import { env } from "./env.js";
7600
+
7601
+ // how this works: one structured logger for the whole API (@lacspace/logger, zero-dep).
7602
+ // In production we emit JSON-per-line (clean for log aggregators); in dev we print a
7603
+ // readable, coloured line. Common secret fields are redacted before anything is logged.
7604
+ const isProd = env.NODE_ENV === "production";
7605
+ export const log = createLogger({
7606
+ level: isProd ? "info" : "debug",
7607
+ transports: [isProd ? jsonConsole() : prettyConsole({ colors: true })],
7608
+ redact: ["password", "token", "authorization", "*.password", "*.token"],
7609
+ });
7610
+
7611
+ // Request logger \u2014 one line per request with method, path, status and duration.
7612
+ // Each request gets a child logger with a short request id you can thread through.
7613
+ export function requestLogger(req: Request, res: Response, next: NextFunction): void {
7614
+ const start = Date.now();
7615
+ const reqId = Math.random().toString(36).slice(2, 10);
7616
+ (req as Request & { log: typeof log }).log = log.child({ reqId });
7617
+ res.on("finish", () => {
7618
+ log.info("request", {
7619
+ reqId,
7620
+ method: req.method,
7621
+ path: req.originalUrl,
7622
+ status: res.statusCode,
7623
+ ms: Date.now() - start,
7624
+ });
7625
+ });
7626
+ next();
7627
+ }
7628
+ `;
7595
7629
  var backendDb = () => `import mongoose from "mongoose";
7596
7630
 
7597
7631
  // how this works: opens the Mongoose connection. Call once at boot.
@@ -7907,16 +7941,19 @@ export default router;
7907
7941
  var backendApp = (ctx) => `import express from "express";
7908
7942
  import cors from "cors";
7909
7943
  import { env } from "./env.js";
7944
+ import { requestLogger } from "./logger.js";
7910
7945
  import { errorHandler } from "./middleware/error.js";
7911
7946
  import { registerRoutes } from "./routes/index.js";
7912
7947
 
7913
7948
  // how this works: assembles the Express app \u2014 CORS for the frontend, JSON parsing,
7914
- // a health check, all route groups (see routes/index.ts), then the error handler LAST.
7949
+ // structured request logging (@lacspace/logger), a health check, all route groups
7950
+ // (see routes/index.ts), then the error handler LAST.
7915
7951
  export function createApp(): express.Express {
7916
7952
  const app = express();
7917
7953
 
7918
7954
  app.use(cors({ origin: env.CORS_ORIGIN.split(",").map((o) => o.trim()), credentials: true }));
7919
7955
  app.use(express.json());
7956
+ app.use(requestLogger); // one structured log line per request
7920
7957
 
7921
7958
  app.get("/health", (_req, res) => { res.json({ ok: true, service: "${ctx.name}-api" }); });
7922
7959
  registerRoutes(app);
@@ -7957,6 +7994,7 @@ function backendFiles(ctx) {
7957
7994
  "backend/src/env.ts": backendEnv(ctx),
7958
7995
  "backend/src/db.ts": backendDb(),
7959
7996
  "backend/src/cache.ts": backendCache(),
7997
+ "backend/src/logger.ts": backendLogger(),
7960
7998
  "backend/src/app.ts": backendApp(ctx),
7961
7999
  "backend/src/http.ts": backendHttp(),
7962
8000
  "backend/src/express.d.ts": backendExpressTypes(),
package/dist/lib.cjs CHANGED
@@ -7472,6 +7472,7 @@ var backendPkgJson = (ctx) => {
7472
7472
  "@lacspace/id": "^1.1.0",
7473
7473
  "@lacspace/rate-limit": "^1.2.0",
7474
7474
  "@lacspace/cache": "^1.1.0",
7475
+ "@lacspace/logger": "^1.0.0",
7475
7476
  ...featureDeps,
7476
7477
  [`${scope(ctx)}/types`]: "*"
7477
7478
  },
@@ -7581,21 +7582,54 @@ var backendIndex = (ctx) => `import "./load-env.js"; // MUST be first: fills pro
7581
7582
  import { env } from "./env.js";
7582
7583
  import { connectDb } from "./db.js";
7583
7584
  import { createApp } from "./app.js";
7585
+ import { log } from "./logger.js";
7584
7586
 
7585
7587
  // how this works: connect to MongoDB, build the Express app, then listen.
7586
7588
  async function main(): Promise<void> {
7587
7589
  await connectDb(env.MONGODB_URI);
7588
7590
  const app = createApp();
7589
7591
  app.listen(env.PORT, () => {
7590
- console.log(\`\u{1F680} ${ctx.name} API ready on http://localhost:\${env.PORT}\`);
7592
+ log.info("${ctx.name} API ready", { url: \`http://localhost:\${env.PORT}\` });
7591
7593
  });
7592
7594
  }
7593
7595
 
7594
7596
  main().catch((err) => {
7595
- console.error("Failed to start the API:", err);
7597
+ log.fatal("Failed to start the API", { err });
7596
7598
  process.exit(1);
7597
7599
  });
7598
7600
  `;
7601
+ var backendLogger = () => `import { createLogger, jsonConsole, prettyConsole } from "@lacspace/logger";
7602
+ import type { Request, Response, NextFunction } from "express";
7603
+ import { env } from "./env.js";
7604
+
7605
+ // how this works: one structured logger for the whole API (@lacspace/logger, zero-dep).
7606
+ // In production we emit JSON-per-line (clean for log aggregators); in dev we print a
7607
+ // readable, coloured line. Common secret fields are redacted before anything is logged.
7608
+ const isProd = env.NODE_ENV === "production";
7609
+ export const log = createLogger({
7610
+ level: isProd ? "info" : "debug",
7611
+ transports: [isProd ? jsonConsole() : prettyConsole({ colors: true })],
7612
+ redact: ["password", "token", "authorization", "*.password", "*.token"],
7613
+ });
7614
+
7615
+ // Request logger \u2014 one line per request with method, path, status and duration.
7616
+ // Each request gets a child logger with a short request id you can thread through.
7617
+ export function requestLogger(req: Request, res: Response, next: NextFunction): void {
7618
+ const start = Date.now();
7619
+ const reqId = Math.random().toString(36).slice(2, 10);
7620
+ (req as Request & { log: typeof log }).log = log.child({ reqId });
7621
+ res.on("finish", () => {
7622
+ log.info("request", {
7623
+ reqId,
7624
+ method: req.method,
7625
+ path: req.originalUrl,
7626
+ status: res.statusCode,
7627
+ ms: Date.now() - start,
7628
+ });
7629
+ });
7630
+ next();
7631
+ }
7632
+ `;
7599
7633
  var backendDb = () => `import mongoose from "mongoose";
7600
7634
 
7601
7635
  // how this works: opens the Mongoose connection. Call once at boot.
@@ -7911,16 +7945,19 @@ export default router;
7911
7945
  var backendApp = (ctx) => `import express from "express";
7912
7946
  import cors from "cors";
7913
7947
  import { env } from "./env.js";
7948
+ import { requestLogger } from "./logger.js";
7914
7949
  import { errorHandler } from "./middleware/error.js";
7915
7950
  import { registerRoutes } from "./routes/index.js";
7916
7951
 
7917
7952
  // how this works: assembles the Express app \u2014 CORS for the frontend, JSON parsing,
7918
- // a health check, all route groups (see routes/index.ts), then the error handler LAST.
7953
+ // structured request logging (@lacspace/logger), a health check, all route groups
7954
+ // (see routes/index.ts), then the error handler LAST.
7919
7955
  export function createApp(): express.Express {
7920
7956
  const app = express();
7921
7957
 
7922
7958
  app.use(cors({ origin: env.CORS_ORIGIN.split(",").map((o) => o.trim()), credentials: true }));
7923
7959
  app.use(express.json());
7960
+ app.use(requestLogger); // one structured log line per request
7924
7961
 
7925
7962
  app.get("/health", (_req, res) => { res.json({ ok: true, service: "${ctx.name}-api" }); });
7926
7963
  registerRoutes(app);
@@ -7961,6 +7998,7 @@ function backendFiles(ctx) {
7961
7998
  "backend/src/env.ts": backendEnv(ctx),
7962
7999
  "backend/src/db.ts": backendDb(),
7963
8000
  "backend/src/cache.ts": backendCache(),
8001
+ "backend/src/logger.ts": backendLogger(),
7964
8002
  "backend/src/app.ts": backendApp(ctx),
7965
8003
  "backend/src/http.ts": backendHttp(),
7966
8004
  "backend/src/express.d.ts": backendExpressTypes(),
package/dist/lib.js CHANGED
@@ -7469,6 +7469,7 @@ var backendPkgJson = (ctx) => {
7469
7469
  "@lacspace/id": "^1.1.0",
7470
7470
  "@lacspace/rate-limit": "^1.2.0",
7471
7471
  "@lacspace/cache": "^1.1.0",
7472
+ "@lacspace/logger": "^1.0.0",
7472
7473
  ...featureDeps,
7473
7474
  [`${scope(ctx)}/types`]: "*"
7474
7475
  },
@@ -7578,21 +7579,54 @@ var backendIndex = (ctx) => `import "./load-env.js"; // MUST be first: fills pro
7578
7579
  import { env } from "./env.js";
7579
7580
  import { connectDb } from "./db.js";
7580
7581
  import { createApp } from "./app.js";
7582
+ import { log } from "./logger.js";
7581
7583
 
7582
7584
  // how this works: connect to MongoDB, build the Express app, then listen.
7583
7585
  async function main(): Promise<void> {
7584
7586
  await connectDb(env.MONGODB_URI);
7585
7587
  const app = createApp();
7586
7588
  app.listen(env.PORT, () => {
7587
- console.log(\`\u{1F680} ${ctx.name} API ready on http://localhost:\${env.PORT}\`);
7589
+ log.info("${ctx.name} API ready", { url: \`http://localhost:\${env.PORT}\` });
7588
7590
  });
7589
7591
  }
7590
7592
 
7591
7593
  main().catch((err) => {
7592
- console.error("Failed to start the API:", err);
7594
+ log.fatal("Failed to start the API", { err });
7593
7595
  process.exit(1);
7594
7596
  });
7595
7597
  `;
7598
+ var backendLogger = () => `import { createLogger, jsonConsole, prettyConsole } from "@lacspace/logger";
7599
+ import type { Request, Response, NextFunction } from "express";
7600
+ import { env } from "./env.js";
7601
+
7602
+ // how this works: one structured logger for the whole API (@lacspace/logger, zero-dep).
7603
+ // In production we emit JSON-per-line (clean for log aggregators); in dev we print a
7604
+ // readable, coloured line. Common secret fields are redacted before anything is logged.
7605
+ const isProd = env.NODE_ENV === "production";
7606
+ export const log = createLogger({
7607
+ level: isProd ? "info" : "debug",
7608
+ transports: [isProd ? jsonConsole() : prettyConsole({ colors: true })],
7609
+ redact: ["password", "token", "authorization", "*.password", "*.token"],
7610
+ });
7611
+
7612
+ // Request logger \u2014 one line per request with method, path, status and duration.
7613
+ // Each request gets a child logger with a short request id you can thread through.
7614
+ export function requestLogger(req: Request, res: Response, next: NextFunction): void {
7615
+ const start = Date.now();
7616
+ const reqId = Math.random().toString(36).slice(2, 10);
7617
+ (req as Request & { log: typeof log }).log = log.child({ reqId });
7618
+ res.on("finish", () => {
7619
+ log.info("request", {
7620
+ reqId,
7621
+ method: req.method,
7622
+ path: req.originalUrl,
7623
+ status: res.statusCode,
7624
+ ms: Date.now() - start,
7625
+ });
7626
+ });
7627
+ next();
7628
+ }
7629
+ `;
7596
7630
  var backendDb = () => `import mongoose from "mongoose";
7597
7631
 
7598
7632
  // how this works: opens the Mongoose connection. Call once at boot.
@@ -7908,16 +7942,19 @@ export default router;
7908
7942
  var backendApp = (ctx) => `import express from "express";
7909
7943
  import cors from "cors";
7910
7944
  import { env } from "./env.js";
7945
+ import { requestLogger } from "./logger.js";
7911
7946
  import { errorHandler } from "./middleware/error.js";
7912
7947
  import { registerRoutes } from "./routes/index.js";
7913
7948
 
7914
7949
  // how this works: assembles the Express app \u2014 CORS for the frontend, JSON parsing,
7915
- // a health check, all route groups (see routes/index.ts), then the error handler LAST.
7950
+ // structured request logging (@lacspace/logger), a health check, all route groups
7951
+ // (see routes/index.ts), then the error handler LAST.
7916
7952
  export function createApp(): express.Express {
7917
7953
  const app = express();
7918
7954
 
7919
7955
  app.use(cors({ origin: env.CORS_ORIGIN.split(",").map((o) => o.trim()), credentials: true }));
7920
7956
  app.use(express.json());
7957
+ app.use(requestLogger); // one structured log line per request
7921
7958
 
7922
7959
  app.get("/health", (_req, res) => { res.json({ ok: true, service: "${ctx.name}-api" }); });
7923
7960
  registerRoutes(app);
@@ -7958,6 +7995,7 @@ function backendFiles(ctx) {
7958
7995
  "backend/src/env.ts": backendEnv(ctx),
7959
7996
  "backend/src/db.ts": backendDb(),
7960
7997
  "backend/src/cache.ts": backendCache(),
7998
+ "backend/src/logger.ts": backendLogger(),
7961
7999
  "backend/src/app.ts": backendApp(ctx),
7962
8000
  "backend/src/http.ts": backendHttp(),
7963
8001
  "backend/src/express.d.ts": backendExpressTypes(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-lacspace-app",
3
- "version": "2.12.0",
3
+ "version": "2.13.0",
4
4
  "description": "Scaffold a beautiful, production-ready Next.js app from a Lacspace template — portfolio, business, e-commerce, SaaS, blog, docs, dashboard, restaurant or marketplace — pre-wired with SEO, security headers, sitemap and robots. Use it as a CLI (like create-next-app, but you start gorgeous) or import it as a library to generate projects programmatically.",
5
5
  "type": "module",
6
6
  "bin": {