Skip to content

feat!: upgrade to json-server v1 (beta.12), maintain js/ts file support #131

Merged
codfish merged 2 commits intomainfrom
feat/upgrade-v1
Mar 8, 2026
Merged

feat!: upgrade to json-server v1 (beta.12), maintain js/ts file support #131
codfish merged 2 commits intomainfrom
feat/upgrade-v1

Conversation

@codfish
Copy link
Owner

@codfish codfish commented Mar 8, 2026

  • Upgrade json-server from v0.17.4 to v1.0.0-beta.12
  • Rewrite server.js to use json-server's programmatic API (createApp + lowdb) instead of the CLI wrapper
  • Migrate from npm to pnpm, Node 20 to Node 24, CJS to ESM, and TypeScript 4 to 5
  • Update all examples, CI workflows, Dockerfile, and README

Breaking Changes

Removed environment variables

The following env vars are no longer supported (json-server v1 dropped them entirely):

  • DELAY - Add delay to responses
  • ID - Set database id property
  • FKS / FOREIGN_KEY_SUFFIX - Set foreign key suffix
  • NO_CORS - Disable CORS
  • NO_GZIP - Disable gzip
  • READ_ONLY - Allow only GET requests
  • QUIET - Suppress log output
  • SNAPSHOTS - Set snapshots directory
  • CONFIG - Path to config file
  • MIDDLEWARES - Paths to multiple middleware files

Only DEPENDENCIES and STATIC remain.

Removed files

  • routes.json - json-server v1 has no custom routes support. The file and all references have been removed.

Removed query parameters

  • q - Full-text search is no longer supported in v1.
  • _expand - Use _embed instead.
  • _start / _end / _limit - Pagination is now _page and _per_page.

ESM required

All mounted files (db, middleware, supporting files) must now use ESM syntax:

  • module.exports = ... → export default ...
  • require(...) → import ... from ...
  • export = ... (TypeScript) → export default ...
  • TypeScript imports of local files need .js extensions (e.g., import foo from './fixtures/bar.js')

Single middleware file only

The MIDDLEWARES env var (which accepted multiple space-separated filenames) has been removed. Mount a single
middleware.{js,ts} file instead. If you need multiple middleware behaviors, combine them into one file.

Node 24 base image

The Docker image now uses node:24-slim (previously node:20.20.0-slim).

pnpm

The image uses pnpm instead of npm. The DEPENDENCIES env var still works but installs via pnpm add internally.

Test plan

  • docker compose build basic && docker compose up basic - JSON db works at localhost:9999
  • docker compose up middlewares - custom middleware sets X-Middleware-A and X-Middleware-B response headers
  • pnpm lint passes
  • pnpm build / tsc --noEmit passes
  • docker compose up - all services start without errors
  • docker compose up typescript - TS db file generates data
  • docker compose up deps - extra dependencies install and work

Summary by CodeRabbit

Release Notes

  • Chores

    • Upgraded Node.js runtime to v24
    • Migrated package manager from npm to pnpm
    • Updated json-server to v1.0.0-beta.12
    • Modernized codebase to ES modules
    • Updated GitHub Actions workflows to latest versions
    • Simplified TypeScript configuration
  • Documentation

    • Updated README for json-server v1 usage and features

@coderabbitai
Copy link

coderabbitai bot commented Mar 8, 2026

📝 Walkthrough

Walkthrough

This PR upgrades the project from Node 20 to 24, migrates from npm to pnpm, converts the codebase from CommonJS to ES modules, upgrades json-server from v0 to v1 beta, rewrites the server bootstrap logic, modernizes GitHub Actions workflows, and updates tooling and documentation accordingly.

Changes

Cohort / File(s) Summary
GitHub Actions Workflows
.github/workflows/release.yml, .github/workflows/validate.yml
Docker action versions upgraded (v3→v4 for login, v5→v6 for metadata, v6→v7 for build-push). Node setup replaced with codfish action; npm workflow replaced with pnpm. GitHub Script replaced with codfish/actions/comment for PR comments with adjusted formatting.
Node.js Runtime & Version
.nvmrc, Dockerfile, package.json
Node version updated from 20.20.0 to 24. PNPM installation and configuration added to Dockerfile. Corepack enabled. Package manager declared as pnpm@10.30.3; module type set to "module" (ESM). Dependencies substantially updated: json-server v0.17.4→1.0.0-beta.12, typescript v4.9.5→v5.8.0, and others.
Build & Configuration
tsconfig.json, eslint.config.js, renovate.json, routes.json
TypeScript config simplified: target es5→es2022, module commonjs→nodenext, added exclude for dist/examples/node_modules. New ESLint config added importing codfish preset. Renovate config formatting compacted. routes.json emptied.
Server Implementation
server.js, server.mjs
Entire server bootstrap rewritten: server.mjs (78 lines, npm/json-server CLI) removed; server.js (153 lines) added with dynamic dependency installation, pnpm build execution, LowDB persistence, static file serving, optional middleware loading, and detailed logging.
Module System Migration (CommonJS → ESM)
db.js, middleware.js, examples/deps/db.js, examples/middlewares/middleware.ts, examples/middlewares/middleware_a.ts, examples/middlewares/middleware_b.ts, examples/support-files/db.ts, examples/support-files/fixtures/dogs.ts, examples/typescript/db.ts, examples/typescript/middleware.ts
All files converted from CommonJS (module.exports / export =) to ES module default exports (export default). middleware_a.ts and middleware_b.ts removed and consolidated into middleware.ts. faker.internet.userName()→faker.internet.username().
Container & Deployment
Dockerfile, docker-compose.yml
Dockerfile base image updated to node:24-slim; dependency installation switched from npm to pnpm with frozen lockfile. Entrypoint changed from nodemon server.mjs to pnpm start. docker-compose.yml port mappings adjusted (80→3000+), volume mounts added for server.js/middleware.js/db.js, environment variables added, middleware configuration consolidated to single middleware.ts.
Project Documentation
README.md
Comprehensive update from json-server v0 to v1 beta documentation: image tag 0.17.4→1.0.0-beta.12, examples migrated to v1 API, environment variables documented, TypeScript guidance updated to ESM, port mappings adjusted, code samples converted from CommonJS to ESM syntax.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • feat: upgrade to v0.17.4 #129: Modifies json-server dependency in package.json; this PR upgrades json-server from v0.17.4 to v1.0.0-beta.12, representing a major version migration with corresponding code changes throughout the project.

Poem

🐰 Hoppy times with Node v24!
From CommonJS to modules so neat,
Pnpm replaces npm's beat,
Server reborn with LowDB delight,
json-server v1 shines oh so bright!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: upgrading json-server to v1 with breaking changes (indicated by !) and commitment to maintaining JavaScript/TypeScript file support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/upgrade-v1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codfish codfish changed the title Feat/upgrade v1 feat!: upgrade to json-server v1 (beta.12), maintain js/ts file support Mar 8, 2026
@codfish codfish force-pushed the feat/upgrade-v1 branch 3 times, most recently from 595b95a to b74ef49 Compare March 8, 2026 21:54
BREAKING CHANGE: json-server v1 is a ground-up rewrite. See PR description
for the full list of breaking changes.
@github-actions
Copy link

github-actions bot commented Mar 8, 2026

🚀 PR build published. Run docker run -p 3000:3000 codfish/json-server@sha256:5019a1592d36b9114b85c3089ca1b835b0bdbe94229211be1551954f6005dbaf

@codfish codfish marked this pull request as ready for review March 8, 2026 22:19
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
db.js (1)

3-14: ⚠️ Potential issue | 🔴 Critical

Fix callback signature to capture the index parameter correctly.

faker.helpers.multiple passes two parameters to the callback: a placeholder value and the 0-based index. The current code uses idx => which captures the placeholder value as the first parameter, leaving the index (second parameter) unused. Change to (_, idx) => so that idx receives the actual index value.

export default () => ({
  users: faker.helpers.multiple(
    (_, idx) => ({
      id: idx,
      name: faker.person.fullName(),
      username: faker.internet.username(),
      email: faker.internet.email(),
      phone: faker.phone.number(),
      website: faker.internet.url(),
    }),
    { count: 10 },
  ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@db.js` around lines 3 - 14, The callback passed to faker.helpers.multiple
currently uses a single parameter (idx) which receives the placeholder value, so
the real 0-based index is ignored; update the callback signature in the users
creation (the call to faker.helpers.multiple) to accept the placeholder and
index as (_, idx) => so that id: idx uses the actual index value from the
multiple helper.
🧹 Nitpick comments (5)
package.json (1)

15-25: Runtime dependencies include dev-time packages.

@types/node, typescript, and nodemon are typically placed in devDependencies. However, if these are intentionally in dependencies for Docker builds (where pnpm install --prod might be used), consider adding a comment in the README explaining this decision.

If these are required at runtime for the Docker workflow (e.g., compiling TypeScript on container start), this is fine. Otherwise, moving them to devDependencies would follow standard conventions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 15 - 25, package.json currently lists
build/tooling packages ("@types/node", "typescript", "nodemon") under
"dependencies"; move these three entries into "devDependencies" (or, if they are
intentionally required at runtime for your Docker workflow, add a clear note to
the README explaining why they must remain in "dependencies") so the dependency
intent is correct; update the "dependencies" and "devDependencies" sections
accordingly and ensure any Docker or start scripts that rely on runtime
compilation are documented.
server.js (2)

77-121: Reliance on json-server internal app.middleware array.

Directly manipulating app.middleware depends on json-server's internal implementation, which may change between versions. Since this PR uses a beta version (1.0.0-beta.12), the API could change before stable release.

Consider documenting this coupling or adding a comment noting the version dependency.

📝 Suggested documentation
+// IMPORTANT: This relies on json-server v1's internal tinyhttp app structure.
+// The middleware array is prepended to ensure user middleware runs before
+// json-server's route handlers. This may need adjustment if json-server's
+// internals change in future versions.
 app.middleware.unshift(...prependMiddleware);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server.js` around lines 77 - 121, The code directly mutates json-server's
internal app.middleware array (see app.middleware.unshift(...prependMiddleware)
and the prependMiddleware entries, including request logger and imported
middlewareMod.default), which is brittle across json-server versions; add a
concise comment above this block documenting the dependency on json-server
1.0.0-beta.12 behavior, why we must unshift into app.middleware (to run before
json-server route handlers), and note a TODO to revisit this if json-server's
API changes (or wrap with a feature-detection fallback if possible).

35-37: Consider validating the public directory copy destination.

fs.copy('public', 'dist') copies the contents of public into dist, which could overwrite compiled files if there are naming conflicts. This might be intentional, but worth noting.

Consider using fs.copy('public', 'dist/public') if the intent is to preserve the public subdirectory structure, or document that public files can override compiled output.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server.js` around lines 35 - 37, The current copy call
(fs.pathExists('public') then fs.copy('public', 'dist')) may overwrite built
artifacts; update the copy to preserve a subdirectory or guard against conflicts
by either copying into a nested folder (use fs.copy('public', 'dist/public')) or
perform a pre-check for conflicting paths and call fs.copy with safe options
(e.g., overwrite:false) and log or fail on conflicts; locate the logic around
fs.pathExists and fs.copy in server.js and implement one of these safe behaviors
and document the chosen approach.
docker-compose.yml (1)

1-1: Consider removing the deprecated version field.

Docker Compose V2+ no longer requires the version field, and version: '3' is considered obsolete. Removing it avoids deprecation warnings.

✨ Suggested change
-version: '3'
-
 services:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docker-compose.yml` at line 1, Remove the deprecated top-level "version: '3'"
entry from docker-compose.yml; locate the literal "version: '3'" line and delete
it so the compose file relies on Compose V2+ schema without the obsolete version
field, then run a quick docker-compose config or lint to ensure the file remains
valid.
examples/middlewares/middleware.ts (1)

1-6: Consider adding TypeScript type annotations for middleware parameters.

The middleware function works correctly but lacks explicit types. Adding types would improve developer experience and catch potential misuse.

✨ Suggested improvement with type annotations
+import type { Request, Response, NextFunction } from 'express';
+
-export default (req, res, next) => {
+export default (req: Request, res: Response, next: NextFunction) => {
   res.set('X-Middleware-A', 'is applied!');
   res.set('X-Middleware-B', 'is applied!');

   next();
 };

Note: You may need to add @types/express as a dev dependency if not already present.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/middlewares/middleware.ts` around lines 1 - 6, Update the
default-exported middleware to use Express types: import Request, Response, and
NextFunction from 'express' and annotate the parameters on the exported function
(req: Request, res: Response, next: NextFunction); adjust the function signature
for the exported anonymous middleware accordingly so editors and the typechecker
know these types (add `@types/express` as a dev dependency if your project lacks
it).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dockerfile`:
- Around line 6-21: The Dockerfile currently runs the app as root (no USER
instruction); create a dedicated non-root user (e.g., appuser) and set ownership
of the app directory before switching to that user so the process started by
ENTRYPOINT (pnpm start) does not run as root. Add steps after creating /app and
copying files to chown the directory (ensure files like package.json,
pnpm-lock.yaml, tsconfig.json, db.js, middleware.js, server.js are owned by the
new user) and add a USER instruction to switch to the non-root account before
the existing ENTRYPOINT, using the user name you create.

In `@examples/support-files/db.ts`:
- Around line 5-6: The exported factory in the default export exposes the
dataset under the wrong key name "dags"; rename the object property "dags" to
"dogs" in the default export so the generated collection matches the fixtures
and routes (update the property where the arrow function returns { dags:
faker.helpers.multiple(generateDog, { count: 10 }) } to use "dogs" instead),
leaving generateDog and the rest unchanged.

In `@package.json`:
- Line 19: The dependency "json-server": "1.0.0-beta.12" in package.json is a
beta pre-release; replace it with a stable, supported alternative or pin to a
well-known stable version (e.g., a published 0.x stable release) or a vetted
commit/tag, and document the rationale in package.json or the repo README;
update any related scripts or tests referencing json-server and run npm/yarn
install + CI to verify compatibility (look for the "json-server" entry in
package.json to locate the change).

In `@README.md`:
- Around line 74-77: Replace the non-descriptive link text "here" with a
meaningful description that conveys the link target (e.g., "codfish/json-server
Docker image tags on Docker Hub") so screen readers and users know where the
link goes; update the anchor text that currently reads "here" (pointing to
https://hub.docker.com/r/codfish/json-server/tags) in the README.md paragraph
about image tags.

In `@server.js`:
- Around line 19-23: The shell invocation uses incorrect zx syntax (await
$([command])) so the command never runs; replace that call with a tagged
template literal using the command variable (e.g., await $`${command}`) so zx
executes the pnpm add command; keep the surrounding logic that checks extraDeps
and writes '.cache' (extraDeps, cache, command, and fs.writeFile remain
unchanged).

In `@tsconfig.json`:
- Around line 8-10: Remove the unused path alias entry from tsconfig.json by
deleting the "@/*": ["./api/*"] mapping inside the "paths" object (and remove
the "paths" key entirely if it becomes empty); ensure the resulting JSON stays
valid (no trailing commas) and search for any remaining references to the "@/*"
alias or the "api/" directory to confirm nothing else relies on it.

---

Outside diff comments:
In `@db.js`:
- Around line 3-14: The callback passed to faker.helpers.multiple currently uses
a single parameter (idx) which receives the placeholder value, so the real
0-based index is ignored; update the callback signature in the users creation
(the call to faker.helpers.multiple) to accept the placeholder and index as (_,
idx) => so that id: idx uses the actual index value from the multiple helper.

---

Nitpick comments:
In `@docker-compose.yml`:
- Line 1: Remove the deprecated top-level "version: '3'" entry from
docker-compose.yml; locate the literal "version: '3'" line and delete it so the
compose file relies on Compose V2+ schema without the obsolete version field,
then run a quick docker-compose config or lint to ensure the file remains valid.

In `@examples/middlewares/middleware.ts`:
- Around line 1-6: Update the default-exported middleware to use Express types:
import Request, Response, and NextFunction from 'express' and annotate the
parameters on the exported function (req: Request, res: Response, next:
NextFunction); adjust the function signature for the exported anonymous
middleware accordingly so editors and the typechecker know these types (add
`@types/express` as a dev dependency if your project lacks it).

In `@package.json`:
- Around line 15-25: package.json currently lists build/tooling packages
("@types/node", "typescript", "nodemon") under "dependencies"; move these three
entries into "devDependencies" (or, if they are intentionally required at
runtime for your Docker workflow, add a clear note to the README explaining why
they must remain in "dependencies") so the dependency intent is correct; update
the "dependencies" and "devDependencies" sections accordingly and ensure any
Docker or start scripts that rely on runtime compilation are documented.

In `@server.js`:
- Around line 77-121: The code directly mutates json-server's internal
app.middleware array (see app.middleware.unshift(...prependMiddleware) and the
prependMiddleware entries, including request logger and imported
middlewareMod.default), which is brittle across json-server versions; add a
concise comment above this block documenting the dependency on json-server
1.0.0-beta.12 behavior, why we must unshift into app.middleware (to run before
json-server route handlers), and note a TODO to revisit this if json-server's
API changes (or wrap with a feature-detection fallback if possible).
- Around line 35-37: The current copy call (fs.pathExists('public') then
fs.copy('public', 'dist')) may overwrite built artifacts; update the copy to
preserve a subdirectory or guard against conflicts by either copying into a
nested folder (use fs.copy('public', 'dist/public')) or perform a pre-check for
conflicting paths and call fs.copy with safe options (e.g., overwrite:false) and
log or fail on conflicts; locate the logic around fs.pathExists and fs.copy in
server.js and implement one of these safe behaviors and document the chosen
approach.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 00ef629a-0ffe-43cf-96f4-286f7243f56c

📥 Commits

Reviewing files that changed from the base of the PR and between ebd5dfd and e19df4f.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (23)
  • .github/workflows/release.yml
  • .github/workflows/validate.yml
  • .nvmrc
  • Dockerfile
  • README.md
  • db.js
  • docker-compose.yml
  • eslint.config.js
  • examples/deps/db.js
  • examples/middlewares/middleware.ts
  • examples/middlewares/middleware_a.ts
  • examples/middlewares/middleware_b.ts
  • examples/support-files/db.ts
  • examples/support-files/fixtures/dogs.ts
  • examples/typescript/db.ts
  • examples/typescript/middleware.ts
  • middleware.js
  • package.json
  • renovate.json
  • routes.json
  • server.js
  • server.mjs
  • tsconfig.json
💤 Files with no reviewable changes (4)
  • examples/middlewares/middleware_a.ts
  • server.mjs
  • routes.json
  • examples/middlewares/middleware_b.ts

Comment on lines 6 to +21
RUN mkdir /app
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci --omit=dev
RUN npm install -g --save-exact nodemon@3.0.1
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod

# copy in files
COPY ./tsconfig.json \
./db.js \
./middleware.js \
./routes.json \
./server.mjs ./
./server.js ./

EXPOSE 80
EXPOSE 3000
ENV PORT=3000

ENTRYPOINT [ "nodemon", "server.mjs" ]
ENTRYPOINT [ "pnpm", "start" ]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Run the container as a non-root user.

This image still starts the server as root because there is no USER instruction. For a network-facing process, that needlessly increases the blast radius of any compromise.

🔒 Proposed fix
 RUN mkdir /app
 WORKDIR /app

 COPY package.json pnpm-lock.yaml ./
 RUN pnpm install --frozen-lockfile --prod

 # copy in files
 COPY ./tsconfig.json \
      ./db.js \
      ./middleware.js \
      ./server.js ./

 EXPOSE 3000
 ENV PORT=3000
+RUN chown -R node:node /app
+USER node

 ENTRYPOINT [ "pnpm", "start" ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RUN mkdir /app
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
RUN npm install -g --save-exact nodemon@3.0.1
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod
# copy in files
COPY ./tsconfig.json \
./db.js \
./middleware.js \
./routes.json \
./server.mjs ./
./server.js ./
EXPOSE 80
EXPOSE 3000
ENV PORT=3000
ENTRYPOINT [ "nodemon", "server.mjs" ]
ENTRYPOINT [ "pnpm", "start" ]
RUN mkdir /app
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod
# copy in files
COPY ./tsconfig.json \
./db.js \
./middleware.js \
./server.js ./
EXPOSE 3000
ENV PORT=3000
RUN chown -R node:node /app
USER node
ENTRYPOINT [ "pnpm", "start" ]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` around lines 6 - 21, The Dockerfile currently runs the app as
root (no USER instruction); create a dedicated non-root user (e.g., appuser) and
set ownership of the app directory before switching to that user so the process
started by ENTRYPOINT (pnpm start) does not run as root. Add steps after
creating /app and copying files to chown the directory (ensure files like
package.json, pnpm-lock.yaml, tsconfig.json, db.js, middleware.js, server.js are
owned by the new user) and add a USER instruction to switch to the non-root
account before the existing ENTRYPOINT, using the user name you create.

Comment on lines +5 to 6
export default () => ({
dags: faker.helpers.multiple(generateDog, { count: 10 }),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Rename the collection key to dogs.

Line 6 exposes this example dataset as dags, so consumers will get /dags instead of /dogs. That makes the support-file example inconsistent with examples/support-files/fixtures/dogs.ts and likely breaks any dog-focused example flow.

🐛 Proposed fix
 export default () => ({
-  dags: faker.helpers.multiple(generateDog, { count: 10 }),
+  dogs: faker.helpers.multiple(generateDog, { count: 10 }),
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export default () => ({
dags: faker.helpers.multiple(generateDog, { count: 10 }),
export default () => ({
dogs: faker.helpers.multiple(generateDog, { count: 10 }),
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/support-files/db.ts` around lines 5 - 6, The exported factory in the
default export exposes the dataset under the wrong key name "dags"; rename the
object property "dags" to "dogs" in the default export so the generated
collection matches the fixtures and routes (update the property where the arrow
function returns { dags: faker.helpers.multiple(generateDog, { count: 10 }) } to
use "dogs" instead), leaving generateDog and the rest unchanged.

"nodemon": "3.1.13",
"typescript": "^4.9.5",
"zx": "^7.2.3"
"json-server": "1.0.0-beta.12",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

json-server 1.0.0 stable release date

💡 Result:

As of March 8, 2026, json-server 1.0.0 (stable/final) has not been released, so there is no stable release date for v1.0.0.

What exists instead is a 1.0.0 beta series (e.g., tags like v1.0.0-beta.0 and v1.0.0-beta.3 are dated May 13, 2024 and Sep 24, 2024 on GitHub) and npm also presents the 1.x line as beta documentation/versions. [1] [2] [3]


Consider the implications of using a beta version of json-server.

json-server@1.0.0-beta.12 is a pre-release version. As of March 2026, v1.0.0 stable has not been released. Beta versions carry risks of breaking changes and instability; long-term support status is unclear.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` at line 19, The dependency "json-server": "1.0.0-beta.12" in
package.json is a beta pre-release; replace it with a stable, supported
alternative or pin to a well-known stable version (e.g., a published 0.x stable
release) or a vetted commit/tag, and document the rationale in package.json or
the repo README; update any related scripts or tests referencing json-server and
run npm/yarn install + CI to verify compatibility (look for the "json-server"
entry in package.json to locate the change).

Comment on lines +74 to +77
> It's recommended to specify the tag of the image you want rather than using the latest image, which might break. Image
> tags are based off of the [release versions for json-server](https://github.com/typicode/json-server/releases).
> However there is not an image for every version. See the available versions
> [here](https://hub.docker.com/r/codfish/json-server/tags).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use descriptive link text for better accessibility.

The link text "here" on line 77 is not descriptive. Screen readers and users benefit from meaningful link text that describes the destination.

📝 Suggested fix
-> [here](https://hub.docker.com/r/codfish/json-server/tags).
+> [on Docker Hub](https://hub.docker.com/r/codfish/json-server/tags).
🧰 Tools
🪛 LanguageTool

[style] ~75-~75: ‘off of’ might be wordy. Consider a shorter alternative.
Context: ...ich might break. Image > tags are based off of the [release versions for json-server](...

(EN_WORDINESS_PREMIUM_OFF_OF)

🪛 markdownlint-cli2 (0.21.0)

[warning] 77-77: Link text should be descriptive

(MD059, descriptive-link-text)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 74 - 77, Replace the non-descriptive link text "here"
with a meaningful description that conveys the link target (e.g.,
"codfish/json-server Docker image tags on Docker Hub") so screen readers and
users know where the link goes; update the anchor text that currently reads
"here" (pointing to https://hub.docker.com/r/codfish/json-server/tags) in the
README.md paragraph about image tags.

Comment on lines +19 to +23
if (extraDeps && cache.trim() !== extraDeps) {
const command = `pnpm add --save-false ${process.env.DEPENDENCIES}`;
await $([command]);
await fs.writeFile('.cache', extraDeps);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

zx $ tagged template literal syntax

💡 Result:

In zx, $ is a function used as a tagged template literal to run shell commands:

import { $ } from 'zx'

await $`echo hello`

(docfork.com)

Basic syntax

1) Plain command

await $`ls -la`

(docfork.com)

2) Interpolate JavaScript values with ${...}

Interpolations become separate, safely-quoted arguments (zx escapes them for you):

const name = 'foo bar'
await $`mkdir -p /tmp/${name}`

(github.com)

3) The “tagged template” part (what the backticks mean)

This is standard JS tagged-template syntax: a function name immediately followed by a template literal, like tag\...``. (developer.mozilla.org)

Common gotchas (zx-specific quoting behavior)

  • ~ (home dir) won’t expand if it’s inside an interpolation (${...}).
  • If you interpolate a string that itself contains shell quoting, zx may escape it as one argument, which can make the resulting command invalid. (google.github.io)

Citations:


🏁 Script executed:

find . -name "server.js" -type f

Repository: codfish/json-server-docker

Length of output: 81


🏁 Script executed:

sed -n '15,25p' server.js

Repository: codfish/json-server-docker

Length of output: 374


Incorrect zx command syntax — $([command]) should use tagged template literal.

The zx library's $ function requires a tagged template literal (e.g., $`command`), not a function call. The syntax await $([command]) will not execute the shell command as intended and will likely fail silently or throw an error.

🐛 Proposed fix
 if (extraDeps && cache.trim() !== extraDeps) {
-  const command = `pnpm add --save-false ${process.env.DEPENDENCIES}`;
-  await $([command]);
+  await $`pnpm add --save-false ${process.env.DEPENDENCIES}`;
   await fs.writeFile('.cache', extraDeps);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (extraDeps && cache.trim() !== extraDeps) {
const command = `pnpm add --save-false ${process.env.DEPENDENCIES}`;
await $([command]);
await fs.writeFile('.cache', extraDeps);
}
if (extraDeps && cache.trim() !== extraDeps) {
await $`pnpm add --save-false ${process.env.DEPENDENCIES}`;
await fs.writeFile('.cache', extraDeps);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server.js` around lines 19 - 23, The shell invocation uses incorrect zx
syntax (await $([command])) so the command never runs; replace that call with a
tagged template literal using the command variable (e.g., await $`${command}`)
so zx executes the pnpm add command; keep the surrounding logic that checks
extraDeps and writes '.cache' (extraDeps, cache, command, and fs.writeFile
remain unchanged).

Comment on lines 8 to +10
"paths": {
"@/*": ["./api/*"]
} /* Specify a set of entries that re-map imports to additional lookup locations. */,
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

/* JavaScript Support */
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,
"checkJs": false /* Enable error reporting in type-checked JavaScript files. */,
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */

/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */

/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,

/* Type Checking */
"strict": false /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */

/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if `@/`* import alias is used anywhere
rg -n "@/" --type ts --type js -g '!node_modules'

# Check if api/ directory exists
fd -t d "^api$"

Repository: codfish/json-server-docker

Length of output: 52


Remove the unused @/* path alias from tsconfig.json.

The path alias @/* maps to ./api/*, but neither this alias nor the api/ directory are used anywhere in the codebase. Removing this unused configuration reduces unnecessary complexity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tsconfig.json` around lines 8 - 10, Remove the unused path alias entry from
tsconfig.json by deleting the "@/*": ["./api/*"] mapping inside the "paths"
object (and remove the "paths" key entirely if it becomes empty); ensure the
resulting JSON stays valid (no trailing commas) and search for any remaining
references to the "@/*" alias or the "api/" directory to confirm nothing else
relies on it.

@codfish codfish merged commit 74d1f44 into main Mar 8, 2026
2 checks passed
@codfish codfish deleted the feat/upgrade-v1 branch March 8, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant