Skip to content

feat: support Authentication and Authorization for the proxy#41

Open
jiashengguo wants to merge 8 commits into
mainfrom
auth
Open

feat: support Authentication and Authorization for the proxy#41
jiashengguo wants to merge 8 commits into
mainfrom
auth

Conversation

@jiashengguo

@jiashengguo jiashengguo commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Added signed-request support with --studioAuthKey CLI option
    • Added --signature-tolerance-secs configuration option (default 60 seconds)
    • Requests can now include X-ZenStack-Signature header for authentication
  • Chores

    • Bumped version to 0.5.0
    • Added automated test suite and CI testing integration

- Introduced `--studioAuthKey` option for authentication key from ZenStack Studio.
- Added `--signatureToleranceSecs` option to configure maximum age of signed requests.
- Implemented `createSignatureMiddleware` to verify ed25519 signatures on incoming requests.
- Normalized public key format for signature verification.
- Enhanced server options to include signature tolerance and public API key.
- Updated request handling to enforce signature verification for protected routes.
- Added comprehensive tests for signature verification and middleware functionality.
Copilot AI review requested due to automatic review settings June 16, 2026 14:05
@gitguardian

gitguardian Bot commented Jun 16, 2026

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 2 secrets following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secrets in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
33483236 Triggered Generic High Entropy Secret 649f9b4 src/signature-verifier.test.ts View secret
33485392 Triggered Generic Private Key febf960 test/signature.test.ts View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secrets safely. Learn here the best practices.
  3. Revoke and rotate these secrets.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jiashengguo, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 10 minutes and 32 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e9571487-5033-4881-a4d7-e0c295243075

📥 Commits

Reviewing files that changed from the base of the PR and between 30ad1a6 and b903a43.

📒 Files selected for processing (1)
  • package.json
📝 Walkthrough

Walkthrough

Adds Ed25519 signed-request verification to the ZenStack proxy. A new src/signature.ts module provides key normalization, signature verification, and an Express middleware. The server gains per-request Prisma client resolution based on Bearer token claims. Two new CLI options (--studioAuthKey, --signatureToleranceSecs) wire the feature end-to-end, backed by a full supertest suite and updated README documentation.

Changes

Signed Request Verification Feature

Layer / File(s) Summary
Signature crypto utilities and key normalization
src/signature.ts
Adds normalizePublicKey (converts raw base64/base64url DER to PEM-wrapped format) and verifyEd25519Signature (Node crypto.verify wrapper that returns false on errors).
Express createSignatureMiddleware
src/signature.ts
Adds middleware that parses x-zenstack-signature (t=,v1=), enforces timestamp replay protection, constructs the signed payload from raw query string or request body plus optional Bearer token, verifies the Ed25519 signature, and returns HTTP 401 on failure with rate-limited warning logs.
CLI options and ServerOptions expansion
src/index.ts, src/server.ts
Adds --studioAuthKey and a validated --signatureToleranceSecs CLI option (defaults to 60, rejects non-integer/negative values). Expands ServerOptions with studioAuthKey? and signatureToleranceSecs, and introduces the private UserClaim type.
Server middleware mounting and per-request Prisma resolution
src/server.ts
Introduces resolveEnhancedClient that re-runs enhanceFunc with user identity and policy enforcement for valid non-superuser Bearer claims. startServer captures raw request body, conditionally mounts createSignatureMiddleware on /api/model and /api/schema, and updates the $transaction route and ZenStackMiddleware's getPrisma hook to use resolveEnhancedClient.
Signature utility and middleware tests
test/signature.test.ts
Adds supertest-based tests for normalizePublicKey, verifyEd25519Signature, and createSignatureMiddleware, covering missing/malformed headers, timestamp tolerance, GET/POST/PUT signing, Authorization header coverage, and raw DER key handling.
README docs, package config, and CI test step
README.md, package.json, .github/workflows/build-test.yml
Documents --studioAuthKey and --signature-tolerance-secs options with payload construction rules. Bumps version to 0.5.0, adds test script and supertest dev dependencies. Adds a CI Test step running pnpm test.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐇 A signature hops through the header line,
t= and v1= in perfect design.
The rabbit checks timestamp, body, and key—
Replay attacks? No, those cannot be free!
Ed25519 guards each request with flair,
While resolveEnhancedClient knows who is there. 🔐

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature: adding authentication and authorization support to the proxy. The changes include signature verification, bearer token handling, and Prisma policy enforcement—all core to the auth implementation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch auth

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds request-signature verification and basic Authorization-claim handling to secure the proxy’s API endpoints.

Changes:

  • Introduces Ed25519 request signature utilities + Express middleware for x-zenstack-signature.
  • Adds server-side gating for signed requests (public key + timestamp tolerance) and resolves enhanced Prisma client behavior based on Authorization bearer claims.
  • Adds tests/docs and updates dependencies/scripts to support the new signature middleware.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
test/signature.test.ts End-to-end tests for key normalization, signature verification, and middleware behavior.
src/signature.ts Implements public key normalization, Ed25519 signature verification, and Express signature middleware.
src/signature-verifier.ts Adds a standalone signature verification helper (non-Express) for payload+timestamp validation.
src/signature-verifier.test.ts Adds unit tests for signature-verifier (currently located under src/).
src/server.ts Wires signature middleware into /api/model and /api/schema; adds Authorization-claim based client resolution.
src/index.ts Adds CLI options for auth key and signature tolerance; passes options into startServer.
README.md Documents the signed request header format and payload construction.
package.json Bumps version; adds test script and supertest dev deps.
pnpm-lock.yaml Updates lockfile for new dev dependencies (includes a vitest entry).
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/server.ts
Comment thread src/server.ts Outdated
Comment thread src/signature.ts
Comment thread src/index.ts
Comment thread README.md Outdated
Comment thread pnpm-lock.yaml Outdated
Comment thread src/signature-verifier.test.ts Outdated
Comment thread src/index.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (1)
src/server.ts (1)

417-435: ⚡ Quick win

Consider adding Helmet middleware for security headers.

The static analysis tool flags that this Express app doesn't use Helmet. Helmet sets various HTTP headers that help protect against common web vulnerabilities (XSS, clickjacking, etc.). While not strictly required for an API proxy, it's a low-effort security improvement.

+import helmet from 'helmet'
 // ...
 const app = express()
+app.use(helmet())
 app.use(cors())
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/server.ts` around lines 417 - 435, The Express app initialization is
missing Helmet middleware, which provides important HTTP security headers to
protect against common web vulnerabilities. Import the helmet package and add it
as middleware early in the chain by calling app.use(helmet()) right after the
express app is created (after the line const app = express()). Place this before
or alongside the other middleware like cors() to ensure security headers are
applied to all responses.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@package.json`:
- Around line 53-57: The pnpm-lock.yaml file is out of sync with the updated
dependencies in package.json (specifically the versions of supertest,
typescript, rimraf, copyfiles, and `@types/supertest`). Regenerate the lockfile by
running pnpm install to update pnpm-lock.yaml with the new dependency
specifications, then commit the updated lockfile to the repository to resolve
the CI installation failures.
- Line 22: The "test" script in package.json is too narrow and only runs
test/signature.test.ts, which excludes the src/signature-verifier.test.ts test
suite. Update the "test" script to run both test files instead of just one, so
that all signature-related tests execute in CI. This ensures the complete test
coverage of the newly added signature verification logic.

In `@README.md`:
- Around line 57-61: The signed message format documentation in README.md is
incomplete and does not account for the Authorization token. Update the
documentation to clarify that when a Bearer token is present in the
Authorization header, it must be included in the signed message format.
Specifically, modify the explanation of the signed message format (currently
documented as `payload + timestamp`) to indicate that the format is actually
`payload + timestamp + bearerToken` (or similar notation) when an Authorization
header with a Bearer token is present, and explain what happens when no
Authorization header is provided. This ensures clients implementing the
signature verification will generate valid signatures for both authenticated and
unauthenticated requests.

In `@src/index.ts`:
- Around line 28-31: The `--studioAuthKey` option is defined in the CLI parser
but is never forwarded to the `startServer` function, making it a dead option
that has no effect. Locate where the option is parsed from the command line
arguments and either: (1) extract the studioAuthKey value and pass it to the
`startServer` function call alongside other parameters like `publicApiKey`, or
(2) if the feature is not yet implemented, remove the entire `--studioAuthKey`
option definition to avoid confusing users. Choose based on whether this
authentication feature is intended to be supported.

In `@src/server.ts`:
- Line 383: The variable publicAPIKey is being destructured from options on line
383 and then re-declared with const on line 407, causing a duplicate variable
declaration error. Remove publicAPIKey from the destructuring statement on line
383 (where zenstackPath, port, zmodelConfig, and zmodelSchemaDir are being
extracted) so that publicAPIKey is only declared once when it is later declared
on line 407.
- Around line 302-308: In the conditional block where claim.type === 'user', add
validation to ensure that claim.data exists and is a non-null object before
passing it to the enhanceFunc call. Add a check after the type comparison to
verify claim.data is not undefined or null, and only proceed with the
enhanceFunc invocation if the validation passes. This prevents creating an
enhanced client with an undefined user identity context.

In `@src/signature.ts`:
- Around line 70-77: The signature header parsing in the code that finds
timestampPart and sigPart fails for valid headers with spaces after commas
(e.g., "t=..., v1=...") because the parts are not trimmed after splitting. When
the header contains a space, the part check with startsWith will fail. Add
trim() calls to each part when finding the timestampPart (checking for 't=') and
sigPart (checking for 'v1=') to remove any leading or trailing whitespace before
performing the startsWith checks.
- Around line 97-99: The `authHeader` variable (from
`req.headers['authorization']`) can be a string, string array, or undefined per
Node.js/Express type definitions, but the code only checks for truthiness before
calling `.startsWith()`, which throws a TypeError if the header is an array. Add
a type guard to verify that the header is a string (using `typeof authHeader ===
'string'`) before calling `.startsWith('Bearer ')`. Apply the same fix to the
`x-signature` header extraction that follows, which has the identical
vulnerability.

---

Nitpick comments:
In `@src/server.ts`:
- Around line 417-435: The Express app initialization is missing Helmet
middleware, which provides important HTTP security headers to protect against
common web vulnerabilities. Import the helmet package and add it as middleware
early in the chain by calling app.use(helmet()) right after the express app is
created (after the line const app = express()). Place this before or alongside
the other middleware like cors() to ensure security headers are applied to all
responses.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 26fd14e4-c4e4-4fec-aea5-22170d85c158

📥 Commits

Reviewing files that changed from the base of the PR and between 898c98e and febf960.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • README.md
  • package.json
  • src/index.ts
  • src/server.ts
  • src/signature-verifier.test.ts
  • src/signature-verifier.ts
  • src/signature.ts
  • test/signature.test.ts

Comment thread package.json Outdated
Comment thread package.json
Comment thread README.md Outdated
Comment thread src/index.ts
Comment thread src/server.ts
Comment thread src/server.ts Outdated
Comment thread src/signature.ts
Comment thread src/signature.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (2)
src/index.ts (1)

32-42: ⚠️ Potential issue | 🟠 Major

Align the CLI flag with docs and use strict integer validation.

The CLI registers --signatureToleranceSecs but the README documents --signature-tolerance-secs. Users following the docs will get an unrecognized option error. Additionally, parseInt accepts partial strings like "10s" (parses to 10) and "1.5" (parses to 1). Use kebab-case to match CLI conventions and validate with Number.isInteger() for strict integer checking.

Proposed fix
       new Option(
-        '--signatureToleranceSecs <seconds>',
+        '--signature-tolerance-secs <seconds>',
         'Maximum age (in seconds) of a signed request before it is rejected as a replay. Defaults to 60.'
       )
         .default(60)
         .argParser((v) => {
-          const parsed = parseInt(v, 10)
-          if (isNaN(parsed) || parsed < 0) {
-            throw new CliError(`--signatureToleranceSecs must be a positive integer, got: ${v}`)
+          const parsed = Number(v)
+          if (!Number.isInteger(parsed) || parsed < 0) {
+            throw new CliError(`--signature-tolerance-secs must be a non-negative integer, got: ${v}`)
           }
           return parsed
         })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/index.ts` around lines 32 - 42, The CLI flag `--signatureToleranceSecs`
uses camelCase but the README documents it in kebab-case as
`--signature-tolerance-secs`, causing a mismatch. Additionally, the argParser
using parseInt is too lenient and accepts partial strings like "10s" and
decimals like "1.5". Change the flag name in the Option constructor from
`--signatureToleranceSecs` to `--signature-tolerance-secs` to match CLI
conventions and the documentation. In the argParser function, replace the
parseInt validation logic to use Number.isInteger() for strict integer
validation instead of relying on parseInt which silently truncates invalid
inputs.
src/server.ts (1)

421-434: ⚠️ Potential issue | 🟠 Major

Add verify callback to express.urlencoded middleware to capture rawBody.

The express.urlencoded parser mounted at line 429 does not capture rawBody, but runs before signature verification. When non-GET/DELETE requests with application/x-www-form-urlencoded content reach the signature middleware, it will verify the signature against an empty string instead of the actual body (line 93 in src/signature.ts: req.rawBody ?? ''), causing signature validation to fail or be bypassed.

Proposed fix
+  const captureRawBody = (req: express.Request, _res: express.Response, buf: Buffer) => {
+    ;(req as express.Request & { rawBody?: string }).rawBody = buf.toString('utf8')
+  }
+
   app.use(
     express.json({
       limit: '5mb',
-      verify: (req, _res, buf) => {
-        // Capture the raw body string for use in signature verification.
-        ;(req as express.Request & { rawBody?: string }).rawBody = buf.toString('utf8')
-      },
+      verify: captureRawBody,
     })
   )
-  app.use(express.urlencoded({ extended: true, limit: '5mb' }))
+  app.use(express.urlencoded({ extended: true, limit: '5mb', verify: captureRawBody }))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/server.ts` around lines 421 - 434, The express.urlencoded middleware at
line 429 is missing a verify callback to capture the raw body string. Currently,
only express.json has this callback that sets req.rawBody. When form-urlencoded
requests are processed, the signature middleware (as referenced in
src/signature.ts line 93) will use an empty string for verification instead of
the actual body content, causing signature validation to fail. Add a verify
callback to the express.urlencoded middleware configuration with the same
pattern used in express.json - capture the buffer and store it as a string in
req.rawBody using the same casting approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/server.ts`:
- Line 20: Make the `signatureToleranceSecs` property optional by adding a
question mark to its declaration (change from `signatureToleranceSecs: number`
to `signatureToleranceSecs?: number`). This aligns with the runtime behavior
where `startServer` already has a fallback to 60 seconds when the value is not
provided, and ensures programmatic callers are not forced to provide this value
at compile-time.

---

Outside diff comments:
In `@src/index.ts`:
- Around line 32-42: The CLI flag `--signatureToleranceSecs` uses camelCase but
the README documents it in kebab-case as `--signature-tolerance-secs`, causing a
mismatch. Additionally, the argParser using parseInt is too lenient and accepts
partial strings like "10s" and decimals like "1.5". Change the flag name in the
Option constructor from `--signatureToleranceSecs` to
`--signature-tolerance-secs` to match CLI conventions and the documentation. In
the argParser function, replace the parseInt validation logic to use
Number.isInteger() for strict integer validation instead of relying on parseInt
which silently truncates invalid inputs.

In `@src/server.ts`:
- Around line 421-434: The express.urlencoded middleware at line 429 is missing
a verify callback to capture the raw body string. Currently, only express.json
has this callback that sets req.rawBody. When form-urlencoded requests are
processed, the signature middleware (as referenced in src/signature.ts line 93)
will use an empty string for verification instead of the actual body content,
causing signature validation to fail. Add a verify callback to the
express.urlencoded middleware configuration with the same pattern used in
express.json - capture the buffer and store it as a string in req.rawBody using
the same casting approach.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7ba050e2-4ed3-4788-b80a-a551bd7ff683

📥 Commits

Reviewing files that changed from the base of the PR and between febf960 and 30ad1a6.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • .github/workflows/build-test.yml
  • README.md
  • package.json
  • src/index.ts
  • src/server.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json

Comment thread src/server.ts
zmodelSchemaDir: string
logLevel?: string[]
studioAuthKey?: string
signatureToleranceSecs: number

Copy link
Copy Markdown

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

🏁 Script executed:

#!/bin/bash
# Description: Inspect startServer/ServerOptions usage and tolerance configuration.
# Expect: ServerOptions callers should not need to pass signatureToleranceSecs unless they override the default.
rg -n -C3 '\bstartServer\s*\(|\bServerOptions\b|signatureToleranceSecs' --type ts

Repository: zenstackhq/proxy

Length of output: 2826


🏁 Script executed:

# Search for all startServer function calls across the entire codebase
rg -n 'startServer\s*\(' --type ts

Repository: zenstackhq/proxy

Length of output: 180


🏁 Script executed:

# Check if there are test files or examples that call startServer
fd -e 'ts' -e 'tsx' -e 'js' | xargs rg -l 'startServer' | head -20

Repository: zenstackhq/proxy

Length of output: 87


Keep signatureToleranceSecs optional to match the runtime default.

startServer already falls back to 60 at line 432 with options.signatureToleranceSecs ?? 60, so making this exported option required creates an unnecessary compile-time break for programmatic callers. The only current caller (CLI) always provides the value anyway due to its default, so making the field optional does not affect existing usage and improves the API contract.

Proposed fix
-  signatureToleranceSecs: number
+  signatureToleranceSecs?: number
📝 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
signatureToleranceSecs: number
signatureToleranceSecs?: number
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/server.ts` at line 20, Make the `signatureToleranceSecs` property
optional by adding a question mark to its declaration (change from
`signatureToleranceSecs: number` to `signatureToleranceSecs?: number`). This
aligns with the runtime behavior where `startServer` already has a fallback to
60 seconds when the value is not provided, and ensures programmatic callers are
not forced to provide this value at compile-time.

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.

2 participants