Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Formatted with oxfmt when the repository moved off Biome.
66e0e6c27749815c009b9f27b9b492f27465404d
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ jobs:
- run: pnpm add --global @antelopejs/core
- run: pnpm prepack
- run: pnpm lint
- run: pnpm format:check
- run: pnpm knip
- run: pnpm test
8 changes: 4 additions & 4 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: 'Close stale issues'
name: "Close stale issues"

on:
schedule:
- cron: '30 * * * *'
- cron: "30 * * * *"
workflow_dispatch:

permissions:
Expand All @@ -17,8 +17,8 @@ jobs:
- uses: actions/stale@v9
with:
exempt-issue-labels: pending
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.'
close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity.'
stale-issue-message: "This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days."
close-issue-message: "This issue was closed because it has been stalled for 30 days with no activity."
days-before-stale: 60
days-before-close: 30
operations-per-run: 200
Expand Down
18 changes: 9 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
| --------------------- | --------------------------------------------------------------------------------------- |
| English only | All code must be in English: variable names, function names, comments |
| PNPM only | Always use pnpm, never npm or yarn |
| NO COMMENTS | Code must be self-documenting through clear naming. TSDoc is allowed for public APIs |
| NO COMMENTS | Code must be self-documenting through clear naming. TSDoc is allowed for public APIs |
| NO switch/case | Use objects, maps, or arrays instead |
| NO inline types | Define proper interfaces/types, never use anonymous types like `{a: string, b: number}` |
| Functions ≤ 40 lines | Split into subfunctions if longer |
Expand All @@ -35,23 +35,23 @@ Never use `switch/case` or `if param === 'XXX'` chains. Instead:
// BAD
function getStatus(code: string) {
switch (code) {
case 'A':
return 'Active';
case 'I':
return 'Inactive';
case "A":
return "Active";
case "I":
return "Inactive";
default:
return 'Unknown';
return "Unknown";
}
}

// GOOD
const STATUS_MAP: Record<string, string> = {
A: 'Active',
I: 'Inactive',
A: "Active",
I: "Inactive",
};

function getStatus(code: string) {
return STATUS_MAP[code] ?? 'Unknown';
return STATUS_MAP[code] ?? "Unknown";
}
```

Expand Down
3 changes: 0 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Changelog


## v0.1.2

[compare changes](https://github.com/AntelopeJS/interface-api-util/compare/v0.1.1...v0.1.2)
Expand Down Expand Up @@ -67,12 +66,10 @@

## v0.0.2


### 🏡 Chore

- Initial commit ([ee1b417](https://github.com/AntelopeJS/interface-api-util/commit/ee1b417))

### ❤️ Contributors

- Antony Rizzitelli <upd4ting@gmail.com>

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ Detailed documentation is available in the `docs` directory:

## License

This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
53 changes: 0 additions & 53 deletions biome.json

This file was deleted.

44 changes: 26 additions & 18 deletions docs/1.introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ npm install @antelopejs/interface-api-util
The `assert` function checks whether a condition is truthy. If the condition is falsy, it throws an `HTTPResult` with the specified HTTP status code and error message.

```typescript
function assert<T>(condition: T, code: number, message: string): asserts condition;
function assert<T>(
condition: T,
code: number,
message: string,
): asserts condition;
```

| Parameter | Type | Description |
| ----------- | -------- | ---------------------------------------------------- |
| `condition` | `T` | The value to check (falsy values trigger the error) |
| `code` | `number` | HTTP status code for the error response |
| `message` | `string` | Error message included in the response body |
| Parameter | Type | Description |
| ----------- | -------- | --------------------------------------------------- |
| `condition` | `T` | The value to check (falsy values trigger the error) |
| `code` | `number` | HTTP status code for the error response |
| `message` | `string` | Error message included in the response body |

The function uses TypeScript's `asserts` keyword, so the compiler narrows the type of `condition` to truthy after the call.

Expand Down Expand Up @@ -52,7 +56,11 @@ import { HTTPResult } from "@antelopejs/interface-api";
async function deletePost(postId: string, currentUserId: string) {
const post = await findPost(postId);
assert(post, 404, "Post not found");
assert(post.authorId === currentUserId, 403, "Not authorized to delete this post");
assert(
post.authorId === currentUserId,
403,
"Not authorized to delete this post",
);

await removePost(postId);
return new HTTPResult(200, { deleted: true });
Expand All @@ -72,12 +80,12 @@ function assertValidation<T>(
): T;
```

| Parameter | Type | Default | Description |
| ----------- | ----------------------------- | ------- | ------------------------------------------------------- |
| `body` | `unknown` | | The input value to validate |
| `validator` | `(body: unknown) => T` | | A function that returns the validated value or throws |
| `errorFunc` | `(err: unknown) => unknown` | | Optional error transformer for customizing the response |
| `code` | `number` | `400` | HTTP status code for the error response |
| Parameter | Type | Default | Description |
| ----------- | --------------------------- | ------- | ------------------------------------------------------- |
| `body` | `unknown` | | The input value to validate |
| `validator` | `(body: unknown) => T` | | A function that returns the validated value or throws |
| `errorFunc` | `(err: unknown) => unknown` | | Optional error transformer for customizing the response |
| `code` | `number` | `400` | HTTP status code for the error response |

The function returns the validated value on success. On failure, it throws an `HTTPResult` whose body is either the result of `errorFunc` or the stringified error.

Expand Down Expand Up @@ -137,11 +145,11 @@ function RateLimit(
): MethodDecorator;
```

| Parameter | Type | Description |
| ---------- | ------------------ | -------------------------------------------------------- |
| `limit` | `number` | Maximum number of requests allowed per window |
| `windowMs` | `number` | Window duration in milliseconds |
| `options` | `RateLimitOptions` | Optional custom key function and `429` response body |
| Parameter | Type | Description |
| ---------- | ------------------ | ---------------------------------------------------- |
| `limit` | `number` | Maximum number of requests allowed per window |
| `windowMs` | `number` | Window duration in milliseconds |
| `options` | `RateLimitOptions` | Optional custom key function and `429` response body |

```typescript
interface RateLimitOptions {
Expand Down
14 changes: 14 additions & 0 deletions knip.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { antelopeKnipConfig } from "@antelopejs/tooling-configs/knip";

export default antelopeKnipConfig({
entry: [
// `ajs module test` runs the compiled suites out of this tree, and reads
// src/antelope.test.ts (package.json antelopeJs.test) to build the test
// project; the preset only knows the `src/test/` spelling.
"src/tests/**/*.test.ts",
"src/antelope.test.ts",
],
// `ajs` comes from @antelopejs/core, which CI installs globally rather than
// pulling the whole CLI into every module's dependency tree.
ignoreBinaries: ["ajs"],
});
7 changes: 7 additions & 0 deletions oxfmt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { antelopeFmtPreset } from "@antelopejs/tooling-configs/oxc/fmt";

export default antelopeFmtPreset({
// Drop once tooling-configs ships the shared ignore (AntelopeJS/tooling-configs#5):
// these are Markdown templates with a .yml extension, which oxfmt cannot parse.
ignorePatterns: [".github/ISSUE_TEMPLATE/**"],
});
7 changes: 7 additions & 0 deletions oxlint.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from "oxlint";
import { antelopePreset } from "@antelopejs/tooling-configs/oxc/lint";

export default defineConfig({
extends: [antelopePreset()],
options: { typeAware: true },
});
45 changes: 26 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,55 @@
"description": "AntelopeJS utility functions for API request validation and error handling",
"keywords": [
"antelopejs",
"interface",
"api",
"interface",
"validation"
],
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "git+https://github.com/AntelopeJS/interface-api-util.git"
},
"license": "Apache-2.0",
"packageManager": "pnpm@10.6.5",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist",
"docs",
"skills"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"publishConfig": {
"access": "public",
"provenance": true
},
"scripts": {
"build": "rimraf dist && tsc",
"format": "biome format --write .",
"lint:fix": "biome check --write .",
"lint": "biome check .",
"format": "oxfmt .",
"lint:fix": "oxlint --fix",
"lint": "oxlint",
"prepack": "pnpm run build",
"release": "pnpm run lint && pnpm run prepack && release-it",
"test": "pnpm run build && ajs module test ."
},
"antelopeJs": {
"test": "src/antelope.test.ts",
"skills": [
"./skills"
]
"test": "pnpm run build && ajs module test .",
"format:check": "oxfmt --check .",
"knip": "knip"
},
"devDependencies": {
"@antelopejs/interface-api": "^0.0.5",
"@antelopejs/interface-core": "^0.0.5",
"@biomejs/biome": "2.3.2",
"@antelopejs/tooling-configs": "^0.0.4",
"@types/mocha": "^10.0.10",
"@types/node": "^22.19.15",
"eslint-plugin-perfectionist": "^5.11.0",
"knip": "^6.34.0",
"oxfmt": "^0.66.0",
"oxlint": "1.81.0",
"oxlint-tsgolint": "^7.0.2001",
"release-it": "^19.2.4",
"release-it-changelogen": "^0.1.0",
"rimraf": "^6.1.3",
Expand All @@ -58,8 +62,11 @@
"@antelopejs/interface-api": ">=0.0.3 <1.0.0",
"@antelopejs/interface-core": ">=0.0.3 <1.0.0"
},
"publishConfig": {
"access": "public",
"provenance": true
"packageManager": "pnpm@10.6.5",
"antelopeJs": {
"test": "src/antelope.test.ts",
"skills": [
"./skills"
]
}
}
Loading