From ef4adbe4fa9e77b105877fda67d349cf40a165d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vedran=20Bilopavlovi=C4=87?= Date: Fri, 3 Jul 2026 21:13:58 +0200 Subject: [PATCH] bump 3.19.0 and update skill files --- .claude/skills/npgsqlrest/SKILL.md | 56 ++++- .../npgsqlrest/annotations-reference.md | 7 +- .../npgsqlrest/configuration-reference.jsonc | 202 +++++++++++++++++- .../CommentParsers/AnnotationReference.cs | 4 +- npm/package.json | 2 +- version.txt | 2 +- 6 files changed, 254 insertions(+), 19 deletions(-) diff --git a/.claude/skills/npgsqlrest/SKILL.md b/.claude/skills/npgsqlrest/SKILL.md index 2cb12cd..6c98183 100644 --- a/.claude/skills/npgsqlrest/SKILL.md +++ b/.claude/skills/npgsqlrest/SKILL.md @@ -1,6 +1,6 @@ --- name: npgsqlrest -description: Build and modify REST APIs with NpgsqlRest — exposing PostgreSQL as HTTP endpoints from two sources (database functions/procedures/tables/views, and plain .sql files), driven by SQL comment annotations (no C# needed). Use when working in an NpgsqlRest project: writing or changing endpoint SQL (functions or .sql files), comment annotations (HTTP routing, authorize, cached, proxy, HTTP Custom Types, SSE, MCP, upload), appsettings.json config, or running/troubleshooting the `npgsqlrest` client. +description: Build and modify REST APIs with NpgsqlRest — exposing PostgreSQL as HTTP endpoints from two sources (database functions/procedures/tables/views, and plain .sql files), driven by SQL comment annotations (no C# needed). Use when working in an NpgsqlRest project: writing or changing endpoint SQL (functions or .sql files), comment annotations (HTTP routing, authorize, cached, proxy, HTTP Custom Types, SSE, MCP, upload), appsettings.json config, testing endpoints with SQL test files (`--test`), running in watch mode (`--watch`), or running/troubleshooting the `npgsqlrest` client. --- # Working with NpgsqlRest @@ -67,20 +67,20 @@ Annotations live in **leading line comments** (`-- ...` or `/* ... */`) in a `.s { "NpgsqlRest": { "SqlFileSource": { "Enabled": true, "FilePattern": "sql/**/*.sql" } } } ``` +Files matching `SkipPattern` (default `"*.test.sql"`) are excluded from endpoint discovery — they are test files for the [test runner](#testing-sql-test-files---test), which makes the co-located layout (`app.sql` next to `app.test.sql`) safe. + ```sql -- sql/get-reports.sql -- HTTP GET --- @param $1 from_date --- @param $2 to_date -- @authorize select id, title, created_at from reports -where created_at between $1 and $2; +where created_at between :from_date and :to_date; ``` - **Filename → path**: `get-reports.sql` → `/api/get-reports`. - **Startup Describe = static type checking.** Each statement is parsed/described against the live DB (no execution); SQL errors fail startup (`ErrorMode: Exit`; set `Skip` to log-and-continue). This catches `column does not exist` etc. before serving. -- **Parameters are positional** (`$1, $2`). `@param $N name [type] [default ...]` names/retypes/defaults them (positional params have no native DEFAULT). `@define_param name [type]` creates a *virtual* param (for placeholders/claims; not bound to SQL). +- **Parameters: named (`:name`) or positional (`$1, $2`)** — one style per file (mixing is a startup error). **Prefer named**: the placeholder IS the parameter name (camelCased for the API: `:from_date` → `fromDate`), a repeated name is ONE parameter (also across statements), and claim mappings (`@user_parameters` + `:_user_id`) hook up with zero annotations. `@param` then only handles type/default: `@param from_date default null`, `@param :from_date date` (Describe type hint), `@param from_date type is date` (retype without rename). Positional: `@param $N name [type] [default ...]` names/retypes/defaults. `@define_param name [type]` creates a *virtual* param (placeholders/claims; not bound to SQL). Tokenizer caveats for `:name`: `::casts`, `:=`, and `a[1:3]` never match; a variable slice bound needs a space (`a[1 : n]`). - **Verb inference** when no `HTTP` tag: `SELECT`→GET, `INSERT`→PUT, `UPDATE`→POST, `DELETE`→DELETE, `DO`→POST (most destructive wins). Explicit `-- HTTP POST` overrides. - **Multi-command files** (statements split on `;`) run in **one batch / round-trip** and return a JSON object keyed per statement. Positional annotations apply to the *next* statement (or inline after `;`): - `@result name` — name the result key (default `result1`, `result2`, …) @@ -120,6 +120,9 @@ Same annotations apply to functions and `.sql` files. Confirm exact syntax/alias **Other** - `@rate_limiter_policy name`. `@command_timeout 30s`. `@connection Name` (multi-connection). `@buffer_rows N`. `@validate _email using required, email`. `@error_code_policy 23505 -> 409`. `@upload [for csv|excel|file_system|large_object]`. +**Test files only** (`*.test.sql`, run by `--test` — not endpoint annotations) +- Header: `-- @setup Step ...`, `-- @teardown Step ...`, `-- @connection Name`, `-- @tag a, b`. Inside HTTP blocks: `# @claim name=value`, `# @response name`. Includes: `\i file` / `\ir file`. + ## HTTP Custom Types (outbound HTTP from SQL) A **composite type** whose comment defines an outbound HTTP request. When a routine (or `.sql` param) is of that type, NpgsqlRest performs the call **before** running the endpoint and fills the composite fields. @@ -215,10 +218,48 @@ npgsqlrest # appsettings.json in cwd npgsqlrest ./config/appsettings.json ./config/appsettings.development.json npgsqlrest --connectionstrings:default="Host=localhost;Database=db;Username=postgres;Password=postgres" npgsqlrest --log:minimallevels:npgsqlrest=debug # see every annotation parsed +npgsqlrest ./config.json --test # run SQL test files, then exit (0 pass / 1 fail / 2 error / 3 config / 4 none) +npgsqlrest ./config.json --watch # dev server: restart on SQL file / config / database routine changes +npgsqlrest ./config.json --test --watch # dev test loop: re-run tests on changes ``` Install via the GitHub release binary, `npm install -g npgsqlrest`, or the `vbilopav/npgsqlrest` Docker image. +## Testing: SQL test files (`--test`) + +Tests are plain `.sql` files (glob: `TestRunner.FilePattern`, e.g. `./tests/**/*.test.sql` or co-located next to endpoints). Each file runs on its **own non-pooled connection**, in parallel; endpoints are invoked **in-process** (full pipeline: routing, auth, params, serialization) **on the test's own connection/transaction** — so a test can `begin`, insert fixtures, call the endpoint (it sees the uncommitted rows), assert, and `rollback`. + +```sql +begin; +insert into users (email) values ('x@example.com'); + +/* +GET /api/get-users +# @claim user_id=1 +*/ +select (select status from _response) = 200, 'authenticated caller gets 200'; +select (select body::jsonb @> '[{"email": "x@example.com"}]' from _response), 'fixture listed'; + +rollback; +``` + +Essentials: +- **Assertions**: a SELECT whose first column is `boolean` (2nd column = assertion name), or a `do $$ ... assert ... $$` block. Everything else is arrange/act. +- **HTTP blocks**: block comment, first line `METHOD /full/path` (incl. `/api` prefix). Directives: `# @claim name=value` (repeatable; any claim = authenticated principal, none = anonymous), `# @response name` (custom capture table). Body after a blank line. Response lands in temp table `_response` (`_response_{n}` for 2+ blocks): `status int, body text, content_type text, headers jsonb, is_success boolean`. +- **Per-file header annotations** (leading `--` comments, TEST files only): `-- @setup StepName ...`, `-- @teardown StepName ...`, `-- @connection Name` (perfect isolation: run the file on its own database), `-- @tag smoke, slow`. Reuse scripts with psql-style `\i file` / `\ir file` includes (paste semantics). +- **Setup/Teardown/Steps** (`TestRunner` config): run-once steps in written order — `{ "Sql": ... }` / `{ "SqlFile": ... }` / `{ "Command": ... }`, each with optional `ConnectionName` and `Enabled` (false = ignored wherever referenced; the default config ships disabled examples to flip on). `Setup` runs BEFORE endpoint discovery → it can `create database app_test_{rnd5}` on an admin connection; `TestRunner.ConnectionName` points the whole run at it; teardown drops it (guaranteed — runs even on Ctrl+C/SIGTERM). `{rnd1}`..`{rnd10}` are per-run-stable random tokens (`{rndN_1}`.. for independent instances). +- **Selection**: `--testrunner:filter=login` (path substring/glob), `--testrunner:tag=smoke --testrunner:excludetag=slow`. +- **Endpoint coverage** reports after full runs (on by default; `CoverageThreshold: 100` fails the build naming untested endpoints). `JUnitOutput` for CI. +- **Debugging**: `DetailedReport: true` (richer report); `ResponseTempTable.DebugTable: "_responses_debug"` mirrors every response into a permanent table (survives rollback; query it after the run; not for CI); the `NpgsqlRestTest` log channel at `Verbose` shows every statement and HTTP call. + +## Watch mode (`--watch`) + +One flag (`--watch`, or config `Watch: { "Enabled": true }`), two flavors chosen by `--test`: +- **Server watch** (`--watch`): a supervisor restarts the server (~1s) on `.sql` source changes (SkipPattern-filtered), **configuration file** changes, and **database routine changes** — polling runs the routine discovery query hashed server-side (`Watch:DatabasePollingInterval`, default `2s`; detects create/replace/drop/comment on functions, grants, and type/table shape changes; never fires on unrelated objects). Code generation (TS client, HTTP files) re-runs every cycle. A broken SQL file logs its error and drops only its endpoint (`ErrorMode` forced to `Skip` while watching). +- **Test watch** (`--test --watch`): a changed test re-runs alone; a changed endpoint file or database routine rebuilds endpoints in-process (endpoint delta reported) and re-runs everything; teardown runs once, on exit. + +For Docker Desktop bind mounts set `DOTNET_USE_POLLING_FILE_WATCHER=1` (file events only; database polling is unaffected). + ## Project conventions worth copying (from real projects) - **One schema for the API** (`IncludeSchemas: ["myapi"]`); internal helpers in another schema. @@ -234,5 +275,8 @@ Install via the GitHub release binary, `npm install -g npgsqlrest`, or the `vbil - **HTTP-type directives** are safest **before the request line**. - **Passthrough proxy doesn't run the function** — declare proxy-response params (transform mode) if you need the body executed. - **`HttpClientOptions.Enabled` / `ProxyOptions.Enabled` / `SqlFileSource.Enabled`** must be true for those features. `@cache` on a non-GET HTTP type is ignored with a warning. -- **SQL files:** annotations are in `--`/`/* */` comments; params are positional `$N` (name via `@param`); a startup Describe error fails boot unless `ErrorMode: Skip`; use `@returns` for statements over not-yet-existing objects (temp tables); `DO` blocks can't take `$N` or return values. +- **SQL files:** annotations are in `--`/`/* */` comments; params are named `:name` (preferred — auto-named) or positional `$N` (name via `@param`) — **never mixed in one file** (startup error); a startup Describe error fails boot unless `ErrorMode: Skip`; use `@returns` for statements over not-yet-existing objects (temp tables); `DO` blocks can't take params or return values. +- **A `.sql` file named `*.test.sql` never becomes an endpoint** — `SqlFileSource.SkipPattern` excludes test files by default. +- **Test HTTP block paths must be the FULL path** including `UrlPathPrefix` (`/api/...`) — a bare `/get-users` is a 404 with a warning. +- **`ResponseTempTable.DebugTable` is a dev-only debugging aid** — never enable in CI; combine with `Keep: true` when the run drops its test database. - After changing an annotation, re-run with `--log:minimallevels:npgsqlrest=debug` (or `--validate`) to confirm it parsed as intended. diff --git a/.claude/skills/npgsqlrest/annotations-reference.md b/.claude/skills/npgsqlrest/annotations-reference.md index d9c612c..1dc513a 100644 --- a/.claude/skills/npgsqlrest/annotations-reference.md +++ b/.claude/skills/npgsqlrest/annotations-reference.md @@ -1,6 +1,6 @@ # NpgsqlRest — Full Annotation Reference -Every comment annotation, generated from `npgsqlrest --annotations` (NpgsqlRest v3.18.1). +Every comment annotation, generated from `npgsqlrest --annotations` (NpgsqlRest v3.19.0). Annotations apply to both endpoint sources (database routines via `comment on`, and `.sql` files via leading `--` comments). The `@` prefix is optional. Regenerate with `npgsqlrest --annotations`. ## `http` @@ -188,9 +188,9 @@ Enable file upload for this endpoint, optionally specifying upload handlers. ## `param` - **Aliases:** parameter, param -- **Syntax:** `param is hash of | param is upload metadata | param [type] | param is [type]` +- **Syntax:** `param is hash of | param is upload metadata | param [type] | param is [type] | param type is | param default ` -Configure parameter behavior: hash computation, upload metadata binding, or rename/retype. Rename forms: 'param $1 user_id', 'param $1 user_id integer', 'param $1 is user_id', 'param _old_name better_name'. Works on all endpoint types. +Configure parameter behavior: hash computation, upload metadata binding, rename/retype, retype WITHOUT rename ('param user_id type is integer'), or default value ('param user_id default null'). Rename forms: 'param $1 user_id', 'param $1 user_id integer', 'param $1 is user_id', 'param _old_name better_name'. In SQL files with named (:name) placeholders the parameter is addressed by the placeholder's own name (a leading ':' is tolerated). Works on all endpoint types. ## `sse_path` @@ -352,4 +352,3 @@ Rename a result key in multi-command SQL file responses. N is the 1-based comman - **Syntax:** `define_param [type]` Define a virtual parameter that exists for HTTP matching and claim mapping but is NOT bound to the PostgreSQL command. Useful for SQL file endpoints where you need parameters for comment placeholders or claim mapping without referencing them in SQL. Default type is text. SQL file source only. - diff --git a/.claude/skills/npgsqlrest/configuration-reference.jsonc b/.claude/skills/npgsqlrest/configuration-reference.jsonc index f986c9e..49f8dd8 100644 --- a/.claude/skills/npgsqlrest/configuration-reference.jsonc +++ b/.claude/skills/npgsqlrest/configuration-reference.jsonc @@ -1,5 +1,5 @@ // NpgsqlRest — FULL configuration reference (every option, with inline comments). -// Generated verbatim from: npgsqlrest --config (NpgsqlRest v3.18.1) +// Generated verbatim from: npgsqlrest --config (NpgsqlRest v3.19.0) // This is the source of truth for configuration. Regenerate with: npgsqlrest --config { @@ -885,11 +885,14 @@ // // See https://github.com/serilog/serilog/wiki/Configuration-Basics#minimum-level // Verbose, Debug, Information, Warning, Error, Fatal. + // Set a level to "Off" (aliases "None"/"Silent") to mute that logger entirely; use null (or omit it) to fall back to its built-in default. // Note: NpgsqlRest logger applies to main application logger, which will, by default have the name defined in the ApplicationName setting. + // NpgsqlRestTest is the SQL test runner (--test) channel (see TestRunner:LoggerName): discovery/parsing at Debug, each query and HTTP call at Verbose, notices by severity. // "MinimalLevels": { "NpgsqlRest": "Information", "NpgsqlRestClient": "Information", + "NpgsqlRestTest": "Information", "System": "Warning", "Microsoft": "Warning" }, @@ -1426,6 +1429,173 @@ "ActivityPath": "/stats/activity" }, + // + // SQL test runner. Invoked with the `--test` command-line flag (this section is otherwise inert). + // Discovers *.test.sql files, runs each in an isolated non-pooled connection, can invoke endpoints + // in-process from an embedded `/* GET /path */` block (response captured into a temp table), and + // asserts via boolean-returning SELECTs or `do $$ ... assert ... $$;` blocks. Exit codes: + // 0 pass, 1 failures, 2 errors, 3 config/runner error, 4 no tests found. + // + "TestRunner": { + // + // Glob (same engine as SqlFileSource) selecting test files. Empty disables discovery. Two layouts: + // co-located (app.sql next to app.test.sql — SqlFileSource SkipPattern keeps tests out of the endpoints) + // or a separate tests tree (e.g. "./tests/**/*.test.sql"). + // + "FilePattern": "", + // + // Optional filter narrowing the discovered set — the fast path for iterating on one test: + // npgsqlrest ... --test --testrunner:filter=login + // Matched against each file's cwd-relative path: a value without wildcards is a substring match; + // with wildcards it is the same glob engine as FilePattern. Empty = run everything discovered. + // + "Filter": "", + // + // Tag filtering (comma- or whitespace-separated lists; case-insensitive). A test file declares tags + // with a `-- @tag name [name ...]` header annotation. "Tag" runs only files carrying at least one of + // the listed tags; "ExcludeTag" skips files carrying any of them (exclude wins). Composes with Filter. + // npgsqlrest ... --test --testrunner:tag=smoke --testrunner:excludetag=slow + // + "Tag": "", + "ExcludeTag": "", + // + // Optional: a ConnectionStrings entry to run the tests against instead of the app's main connection. In + // test mode it becomes the connection used for endpoint type-checking (Describe) and execution, so it can + // point at a dedicated test database that a Setup step creates first (it need not exist at startup). + // Empty = use the main connection. Tip: {rnd1}..{rnd10} are random lowercase tokens (length = the digit), + // stable for the whole run, usable in any connection string or Setup/Teardown SQL (e.g. Database=app_test_{rnd6}). + // Need several distinct tokens of the same length? Indexed instances {rndN_1}..{rndN_9} are each independent. + // + "ConnectionName": "", + // + // Max test files run concurrently. 0 => processor count. Each test uses its own non-pooled connection. + // + "MaxParallelism": 0, + // + // Stop scheduling new tests after the first failure/error (in-flight tests still finish). + // + "FailFast": false, + // + // Per-test timeout. Accepts "30s", "5m", "1h", a plain number of seconds, or "hh:mm:ss". 0 disables. + // + "PerTestTimeout": "30s", + // + // Optional path to also write a JUnit XML report (console output is always printed). + // + "JUnitOutput": null, + // + // Skip Teardown so a failed run's state can be inspected. + // + "Keep": false, + // + // Detailed console REPORT: list passed assertions, print the full failing SQL statement, and show + // captured `raise notice` output for passing tests too. This shapes the report only — for diagnostic + // logging of every executed query/HTTP call, raise the log channel instead (Log:MinimalLevels + LoggerName). + // + "DetailedReport": false, + // + // Treat "no tests discovered" as success (exit 0) instead of exit 4. + // + "AllowEmpty": false, + // + // Endpoint-coverage summary after the run: exercised N of M testable endpoints + the list of untested + // ones (endpoint kinds the runner rejects — SSE, upload, login/logout, outbound proxy — are excluded + // from the ratio and counted separately). Tri-state: null (default) reports after FULL runs but stays + // quiet when the run is narrowed by Filter/Tag (a deliberately partial run would just nag); true always + // reports; false never. CoverageThreshold (0-100) always reports and fails an otherwise-passing run + // with exit 2 when coverage is below it — CI gating for "every endpoint has a test". + // + "Coverage": null, + "CoverageThreshold": null, + // + // SourceContext name for the runner's own log channel; set its level independently under Log:MinimalLevels. + // Discovery/parsing log at Debug, each query and HTTP invocation at Verbose, `raise notice` by severity. + // + "LoggerName": "NpgsqlRestTest", + // + // Per-HTTP-block temp table that captures the response. Each block gets its own fresh temp table + // (created without IF NOT EXISTS, so a duplicate name fails the test); writes are pg_temp-qualified. + // A file with ONE HTTP block uses "Name"; a file with 2+ blocks uses "MultiNamePattern" where {n} is + // the 1-based block ordinal (_response_1, _response_2, ...). Per-block override: `# @response `. + // A null/empty column name omits that column. "DebugTable" (e.g. "_responses_debug"): ALSO mirror every + // response into a PERMANENT table for post-run inspection — survives rollbacks, holds the last run, one + // row per HTTP block with test_file/block/method/path metadata (debugging aid; do not enable in CI). + // + "ResponseTempTable": { + "Name": "_response", + "MultiNamePattern": "_response_{n}", + "DebugTable": null, + "Columns": { + "Status": "status", + "Body": "body", + "ContentType": "content_type", + "Headers": "headers", + "IsSuccess": "is_success" + } + }, + // + // Named, reusable steps (name → step; same shape as Setup/Teardown entries). Reference them by name in + // Setup/Teardown below, or from an individual test file's leading header comments: + // -- @setup StepName [StepName ...] runs before that file + // -- @teardown StepName [StepName ...] runs after that file (always, best-effort) + // -- @connection Name runs that file on a named ConnectionStrings entry + // Annotations are repeatable; names may be whitespace- or comma-separated and run in the order written. + // Test files can also reuse SQL scripts in place with psql-style includes: `\i file` (cwd-relative) or + // `\ir file` (relative to the including file) — executed on the test's connection, inside its transaction. + // + // The entries below are disabled EXAMPLES showing every step property ("Sql", "SqlFile", "Command", + // "WorkingDirectory", "ConnectionName") across the typical scenarios — flip "Enabled" to true (and adjust + // names, paths, and connections) instead of typing them from scratch. A step with "Enabled": false is + // simply IGNORED wherever it is referenced. + // + "Steps": { + "CreateTestDatabase": { "Enabled": false, "ConnectionName": "Admin", "Sql": "create database app_test_{rnd5}" }, + "DropTestDatabase": { "Enabled": false, "ConnectionName": "Admin", "Sql": "drop database if exists app_test_{rnd5} with (force)" }, + "ApplySchema": { "Enabled": false, "SqlFile": "./migrations/schema.sql" }, + "RunMigrationTool": { "Enabled": false, "Command": "echo replace with your migration tool command", "WorkingDirectory": "." }, + "StartDockerPostgres": { "Enabled": false, "Command": "docker run -d --name npgsqlrest-test-pg -e POSTGRES_PASSWORD=postgres -p 54329:5432 postgres" }, + "StopDockerPostgres": { "Enabled": false, "Command": "docker rm -f npgsqlrest-test-pg" } + }, + // + // Run-once setup, BEFORE endpoint discovery. Steps run in the EXACT order written. Each entry is a step + // NAME from "Steps" above, or an inline step object: + // { "Command": "...", "WorkingDirectory": "..." } — runs via the OS shell + // { "Sql": "..." } | { "SqlFile": "..." } — runs on the test connection; set "ConnectionName" + // to run on another ConnectionStrings entry (e.g. + // an admin connection that runs `create database`). + // + "Setup": [], + // + // Run-once teardown, ALWAYS (best-effort), in the EXACT order written. `Keep` skips it. Same entries as Setup. + // + "Teardown": [] + }, + + // + // Watch mode (interactive/dev-only) — one feature, two flavors: with --test it re-runs tests on + // changes (a changed test file re-runs alone; a changed endpoint file or database routine rebuilds + // endpoints in-process and re-runs everything; teardown runs once, on exit); without --test it + // supervises the SERVER and restarts it on SQL file source, configuration, and database routine + // changes. In both flavors a broken SQL file cannot kill the session (SqlFileSource ErrorMode is + // forced from Exit to Skip while watching). + // + "Watch": { + // + // Turn watch mode on. The --watch command line flag is the shorthand for this setting. + // + "Enabled": false, + // + // Poll the database for routine changes and restart the server (server watch) or rebuild endpoints and + // re-run the tests (test watch). The poll runs the SAME routine discovery query the endpoint source + // uses (same configured filters), hashed server-side into one value — so it detects exactly what + // changes discovered endpoints: functions/procedures (create/replace/drop/alter, grants), their + // COMMENT ON annotations, and the composite types and tables their signatures use; anything the + // discovery does not read can never trigger. Accepts "2s", "500ms", "1m", a plain number of seconds, + // or "hh:mm:ss"; 0 disables. One query per interval on a dedicated non-pooled connection. + // + "DatabasePollingInterval": "2s" + }, + // // Command retry strategies and options for client and middleware commands. // @@ -2461,7 +2631,11 @@ // // Set to true to overwrite existing files. // - "FileOverwrite": true + "FileOverwrite": true, + // + // When true, parameters filled by the server and not settable by the client are omitted from the generated HTTP file's query string and request body. Covers optional automatic parameters: HTTP Custom Type fields, resolved-parameter expressions, upload metadata, and (on endpoints using user parameters) IP-address and user-claim parameters. Default is false. + // + "OmitAutomaticParameters": false }, // @@ -2563,7 +2737,11 @@ // documented. Anonymous endpoints — typically health, login, probes — are omitted. Useful // for partner-facing documents. Default false = document everything. // - "RequiresAuthorizationOnly": false + "RequiresAuthorizationOnly": false, + // + // When true, parameters filled by the server and not settable by the client are omitted from documented query parameters and request bodies. Covers optional automatic parameters: HTTP Custom Type fields, resolved-parameter expressions, upload metadata, and (on endpoints using user parameters) IP-address and user-claim parameters. Default is false. + // + "OmitAutomaticParameters": false }, // // Enable or disable the MCP (Model Context Protocol) server endpoint. Disabled by default. Tools are NEVER auto-exposed: only routines explicitly opted in with the `mcp` comment annotation become MCP tools. Implements MCP specification 2025-11-25. @@ -2763,7 +2941,11 @@ // // TypeScript type for error response. Only used when IncludeStatusCode is true. // - "ErrorType": "{status: number; title: string; detail?: string | null} | undefined" + "ErrorType": "{status: number; title: string; detail?: string | null} | undefined", + // + // When true, parameters filled by the server and not settable by the client are omitted from the generated request interface, query string, and body. Covers optional automatic parameters: HTTP Custom Type fields, resolved-parameter expressions, upload metadata, and (on endpoints using user parameters) IP-address and user-claim parameters. Default is false. + // + "OmitAutomaticParameters": false }, // @@ -2877,7 +3059,11 @@ // // When true, for upload endpoints marked as proxy, the raw multipart/form-data content is forwarded directly to the upstream proxy instead of being processed locally. This allows the upstream service to handle file uploads. When false (default), upload endpoints with proxy annotation will process uploads locally and upload metadata will not be available to the proxy. // - "ForwardUploadContent": false + "ForwardUploadContent": false, + // + // Maximum length (characters) of a single automatic parameter value appended to the proxy upstream query string. Server-filled values (claims, IP, HTTP Custom Type fields, resolved-parameter expressions) longer than this are skipped with a warning instead of producing an unusable request line (HTTP 414/431). 0 or less disables the guard. To forward a large value, use a body-carrying proxy method (POST/PUT/PATCH). Default is 2048. + // + "MaxForwardedQueryParamLength": 2048 }, // @@ -2896,6 +3082,12 @@ // "FilePattern": "", // + // Glob (same semantics as FilePattern) for files to EXCLUDE from endpoint discovery. + // Default "*.test.sql" so co-located SQL test files (run by the test runner, see "TestRunner") + // are never exposed as endpoints. Empty string disables the exclusion. + // + "SkipPattern": "*.test.sql", + // // How comment annotations are processed for SQL file endpoints. // Possible values: Ignore, ParseAll, OnlyAnnotated, OnlyWithHttpTag. // OnlyAnnotated (default; OnlyWithHttpTag is a back-compat alias) requires an explicit diff --git a/NpgsqlRest/Defaults/CommentParsers/AnnotationReference.cs b/NpgsqlRest/Defaults/CommentParsers/AnnotationReference.cs index a954417..0ba4d52 100644 --- a/NpgsqlRest/Defaults/CommentParsers/AnnotationReference.cs +++ b/NpgsqlRest/Defaults/CommentParsers/AnnotationReference.cs @@ -233,8 +233,8 @@ static JsonArray ToJsonArray(string[] values) { ["name"] = "param", ["aliases"] = ToJsonArray(ParameterKey), - ["syntax"] = "param is hash of | param is upload metadata | param [type] | param is [type]", - ["description"] = "Configure parameter behavior: hash computation, upload metadata binding, or rename/retype. Rename forms: 'param $1 user_id', 'param $1 user_id integer', 'param $1 is user_id', 'param _old_name better_name'. Works on all endpoint types." + ["syntax"] = "param is hash of | param is upload metadata | param [type] | param is [type] | param type is | param default ", + ["description"] = "Configure parameter behavior: hash computation, upload metadata binding, rename/retype, retype WITHOUT rename ('param user_id type is integer'), or default value ('param user_id default null'). Rename forms: 'param $1 user_id', 'param $1 user_id integer', 'param $1 is user_id', 'param _old_name better_name'. In SQL files with named (:name) placeholders the parameter is addressed by the placeholder's own name (a leading ':' is tolerated). Works on all endpoint types." }); annotations.Add((JsonNode)new JsonObject diff --git a/npm/package.json b/npm/package.json index 6cefc2e..53675f0 100644 --- a/npm/package.json +++ b/npm/package.json @@ -1,6 +1,6 @@ { "name": "npgsqlrest", - "version": "3.18.2", + "version": "3.19.0", "description": "Automatic REST API for PostgreSQL Databases Client Build", "scripts": { "postinstall": "node postinstall.js", diff --git a/version.txt b/version.txt index 05d9754..209f579 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -3.18.2 \ No newline at end of file +3.19.0 \ No newline at end of file