Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
7925c60
deno
johanfive May 19, 2025
f0ef959
deno
johanfive May 20, 2025
c7da65e
deno
johanfive May 20, 2025
7abffc9
deno
johanfive Jun 2, 2025
a6fbb83
Refactor test-util and add auto format on save
johanfive Jun 2, 2025
5014001
Rethink types for reusability
johanfive Jun 2, 2025
ed33286
Refine the patterns
johanfive Jun 5, 2025
567d132
Rename FTW
johanfive Jun 5, 2025
d1d8bf6
Move XmApiError out of the types.ts file
johanfive Jun 6, 2025
1b8184a
Move DefaultHttpClient and defaultLogger out of request-handler.ts to…
johanfive Jun 6, 2025
bf3f81b
Take RequestBuilder out of request-hander.ts
johanfive Jun 6, 2025
72553ce
Refactor project structure FTW
johan-friedrich-eb Jun 6, 2025
b4588e1
Get started on endpoint implementation patterns documentation
johan-friedrich-eb Jun 6, 2025
99866ad
Continuing with organizing the types and preparing to implement oauth…
johan-friedrich-eb Jun 6, 2025
a599c46
Simplify XmApi class, and make request-handler and request-builder ma…
johan-friedrich-eb Jun 6, 2025
f873829
Got started on refactoring tests so they make sense
johan-friedrich-eb Jun 8, 2025
16a1b8d
Continue unit test refactoring
johan-friedrich-eb Jun 8, 2025
97b05ea
Continue unit test refactoring
johan-friedrich-eb Jun 8, 2025
f3c8fe8
Remove bloat that was bothering me
johan-friedrich-eb Jun 8, 2025
c7d26b5
Remove the escape hatch from resource-clients.ts
johan-friedrich-eb Jun 8, 2025
84db9c4
Refactor XmApiError
johan-friedrich-eb Jun 8, 2025
13be60d
Unit test the logs
johan-friedrich-eb Jun 8, 2025
6f0c227
Implement OAuth endpoint
johan-friedrich-eb Jun 9, 2025
95aaa4a
Minor types tweak
johan-friedrich-eb Jun 9, 2025
7d104ad
Fix lint error
johan-friedrich-eb Jun 9, 2025
b2c5487
Always throw XmApiError instances
johan-friedrich-eb Jun 9, 2025
ad6b0f4
Make time manipulating tests clearer with inline comments and explici…
johan-friedrich-eb Jun 10, 2025
ab8eda6
Fix the HttpRequest type
johan-friedrich-eb Jun 10, 2025
01eefec
Reduce types bloat
johan-friedrich-eb Jun 10, 2025
585f180
Minor tweaks for accuracy and organization
johan-friedrich-eb Jun 10, 2025
0917aab
Refine the sandbox + finally rename `getGroups` to just `get` for `gr…
johan-friedrich-eb Jun 10, 2025
0dcb2f2
commit stragglers
johan-friedrich-eb Jun 10, 2025
f69eed1
Small tweaks
johan-friedrich-eb Jun 10, 2025
3e3da58
Refine the sandbox
johan-friedrich-eb Jun 10, 2025
0143a18
Add FYI to list of recommended extensions
johanfive Jun 11, 2025
e1fd7cd
Replace "options" semantic with "config" semantic for the XmApi const…
johan-friedrich-eb Jun 12, 2025
42b8d40
Laid out proper plan for proper oauth and credentials DX
johan-friedrich-eb Jun 12, 2025
2288acc
remove the backward compatibility requirement because this is all sti…
johan-friedrich-eb Jun 12, 2025
fac0021
Add a checklist markdown file to support the fact that the agent will…
johan-friedrich-eb Jun 12, 2025
a3b1b1f
Committing the new sandbox first
johan-friedrich-eb Jun 13, 2025
d82cdfe
deno fmt
johan-friedrich-eb Jun 14, 2025
5702ae4
Rewrite oauth and finally got around making RequestHandler great again
johan-friedrich-eb Jun 14, 2025
55ec22f
Clean up doc
johan-friedrich-eb Jun 14, 2025
bd7cb90
Align oauth methods with standard of single arg object
johan-friedrich-eb Jun 15, 2025
0fdb9db
Add User-Agent defaut header. Fix type imports after a restart of the…
johan-friedrich-eb Jun 15, 2025
d6e3ee9
Enhance config validation + make std libs imports great again
johan-friedrich-eb Jun 15, 2025
4f218c5
No more explicitly returning undefined
johan-friedrich-eb Jun 16, 2025
8933eaa
Make extractErrorMessage slightly more resilient + minor cosmetic cha…
johan-friedrich-eb Jun 17, 2025
d2c86d3
Revisit token expiration logic
johan-friedrich-eb Jun 17, 2025
1739929
Remove dead code
johan-friedrich-eb Jun 17, 2025
73688a4
Remove dead code
johan-friedrich-eb Jun 17, 2025
2668979
Remove dead code
johan-friedrich-eb Jun 17, 2025
0e1bea7
Error consistency
johan-friedrich-eb Jun 17, 2025
8fe7743
Build formData safely with new URLSearchParams instead of rawdogging …
johan-friedrich-eb Jun 17, 2025
f9afe9d
Renamed refreshToken method to avoid confusion with property of the s…
johan-friedrich-eb Jun 18, 2025
0d69b8d
renamed file for clarity
johan-friedrich-eb Jun 19, 2025
f20e9af
delete unnecessary file
johan-friedrich-eb Jun 19, 2025
8f0af44
Ensure valid hostname
johan-friedrich-eb Jun 19, 2025
db0727b
Reduce re-exported types list
johan-friedrich-eb Jun 19, 2025
6f1e43b
Get started on unit test refactor
johan-friedrich-eb Jun 19, 2025
e9bea7a
Support loosely defined hostname in config - default to https
johan-friedrich-eb Jun 19, 2025
a94e8a7
Update MockHttpClient to work with `expect` to throw better errors
johan-friedrich-eb Jun 19, 2025
d08b202
Allow consumers to override headers
johan-friedrich-eb Jun 20, 2025
c2611d9
Refine endpoints types system
johan-friedrich-eb Jun 20, 2025
6d506c5
Simplify and expand types
johan-friedrich-eb Jun 21, 2025
0db6d16
Refine testing patterns
johan-friedrich-eb Jun 23, 2025
575e747
Revisit how logs get tested
johan-friedrich-eb Jun 25, 2025
49b6f8f
Simplify MockHttpClient by getting rid of unnecessary requestIndex
johan-friedrich-eb Jun 25, 2025
cc92b73
Small improvements to MockHttpClient
johan-friedrich-eb Jun 25, 2025
41ada79
reformat src/index.test.ts
johan-friedrich-eb Jun 25, 2025
b82d141
Continue refactoring unit tests - remove the ones made redundant by t…
johan-friedrich-eb Jun 26, 2025
a0e1bff
Continue refactoring unit tests
johan-friedrich-eb Jun 26, 2025
368a7a2
Continue refactoring unit tests
johan-friedrich-eb Jun 26, 2025
4b4b6f5
Continue refactoring unit tests
johan-friedrich-eb Jun 28, 2025
a70abc2
Continue refactoring unit tests
johan-friedrich-eb Jun 28, 2025
2ea549f
Get started on cleaning up readme
johan-friedrich-eb Jun 28, 2025
63b6f64
Get started on cleaning up readme
johan-friedrich-eb Jun 28, 2025
7c801c1
Refresh the READMEs
johan-friedrich-eb Jun 28, 2025
984d354
Implement /people endpoint with A.I. and a snippet
johan-friedrich-eb Jun 28, 2025
a6f9f21
Implement Axios adapter
johan-friedrich-eb Jun 29, 2025
37d3c0b
deno fmt
johan-friedrich-eb Jun 29, 2025
4f1e0da
Fix how return types are defined in endpoints
johan-friedrich-eb Jul 1, 2025
3cb6f7c
Readd explicit return types because of deno default linting rules (al…
johan-friedrich-eb Jul 2, 2025
f550dad
Better specify types for Create vs Update scenarios of /groups
johan-friedrich-eb Jul 2, 2025
01394a9
Various small improvements and renamings for quality of life
johan-friedrich-eb Jul 4, 2025
b4905b1
revisit error handling in request handler
johan-friedrich-eb Jul 5, 2025
79c66d1
Figured out a pattern I like for request building options types
johan-friedrich-eb Jul 5, 2025
76b0605
Goldplating
johan-friedrich-eb Jul 5, 2025
6dd8615
Goldplating
johan-friedrich-eb Jul 5, 2025
8e6a607
Goldplating
johan-friedrich-eb Jul 5, 2025
43fa43e
Goldplating
johan-friedrich-eb Jul 5, 2025
c7efc75
Add unit test for oauth endpoint
johan-friedrich-eb Jul 5, 2025
e06441a
Minor legal things
johan-friedrich-eb Jul 11, 2025
f2f6b9f
CI/CD experiment
johan-friedrich-eb Jul 11, 2025
80bb02a
CI/CD experiment
johan-friedrich-eb Jul 11, 2025
141530e
CI/CD experiment
johan-friedrich-eb Jul 11, 2025
9df919c
CI/CD experiment
johan-friedrich-eb Jul 11, 2025
ce52c04
Fix accident in the readme
johan-friedrich-eb Jul 11, 2025
1587839
Extra auth info in readme
johan-friedrich-eb Jul 11, 2025
f89d407
CI/CD no more dry run
johan-friedrich-eb Jul 11, 2025
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
40 changes: 0 additions & 40 deletions .eslintrc.json

This file was deleted.

66 changes: 66 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
This TypeScript project, built with Deno, is a library for JavaScript developers to consume the
xMatters API (aka `xmApi`).

### Project Priorities

1. **Good DX**:

- The library should provide a great developer experience (DX) for JavaScript and TypeScript
developers who use it (consumers), and for those who develop it (maintainers).
- When these 2 priorities are at odds, the library should prioritize a good DX for consumers.
- It should be easy to use, with clear and concise APIs that are intuitive to understand.

2. **Consistency**:

- Code should be consistent in **style**, **structure**, and **behavior**.
- Follow consistent **naming conventions**, **error handling**, and **response structures**.

3. **Zero Dependencies**:

- Do not use any third-party libraries.
- Only use Deno’s standard library, and only for **unit testing**.

4. **Dependency Injection**:

- Consumers must be able to inject their own:
- HTTP client
- Logger
- Any other external dependencies when applicable

5. **Type Safety**:

- Use TypeScript features when they add value, not just because you can.
- Avoid the non-null assertion operator (`!`) entirely.
- Prefer `null` over `undefined` when explicitly assigning absence of a value.

6. **Documentation**: The library should be well-documented, with clear examples and usage
instructions.

### Development Guidelines

It should be extremely easy for the maintainers to add more endpoints in the future. The core logic
of how a request is built and sent should be abstracted away from the endpoint implementations.

- Do not make changes until you are **95% confident** in what needs to be built.
- Ask clarifying questions until you reach that level of confidence.

#### The Sandbox

- `/sandbox/index.ts` is for quick prototyping and testing.
- Though version controlled, this file is **not** part of the library shipped to consumers.
- Do **not** modify the sandbox unless explicitly instructed.
- Must be run with:

```bash
deno task sandbox
```

#### Unit Tests

- **Never** send real HTTP requests.
- Use _mocks_ or _stubs_ for all external interactions.
- Must be run with:

```bash
deno test
```
22 changes: 22 additions & 0 deletions .github/workflows/publishToJsr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Publish to JSR

on:
push:
tags:
- 'v*' # Triggers on version tags like v0.1.0

jobs:
publish:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Deno
uses: denoland/setup-deno@v1
with:
deno-version: v2.x

- name: Publish to JSR
run: deno publish
25 changes: 25 additions & 0 deletions .github/workflows/validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Build

on:
push:
branches:
- '**'

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v2
with:
deno-version: v2.x # Run with latest stable Deno.

- run: deno fmt --check

- run: deno lint

- run: deno test --coverage=cov/

# This generates a report from the collected coverage in `deno test --coverage`. It is
# stored as a .lcov file which integrates well with services such as Codecov, Coveralls and Travis CI.
- run: deno coverage --lcov cov/ > cov.lcov
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
node_modules/
sandbox/config.json
sandbox/index.js
sandbox/.env
dist/
node_modules/
6 changes: 6 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"recommendations": [
"denoland.vscode-deno",
"johanfive.fyi"
]
}
20 changes: 20 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"[typescript]": {
"editor.defaultFormatter": "denoland.vscode-deno",
"editor.formatOnSave": true
},
"[json]": {
"editor.defaultFormatter": "denoland.vscode-deno",
"editor.formatOnSave": true
},
"[jsonc]": {
"editor.defaultFormatter": "denoland.vscode-deno",
"editor.formatOnSave": true
},
"[yaml]": {
"editor.defaultFormatter": "denoland.vscode-deno",
"editor.formatOnSave": true
},
"deno.enable": true,
"deno.lint": true
}
88 changes: 88 additions & 0 deletions .vscode/typescript.code-snippets
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{
"xMatters Endpoint Index": {
"prefix": "xm-endpoint",
"description": "Generate a complete endpoint index.ts file",
"body": [
"import { ResourceClient } from 'core/resource-client.ts';",
"import type {",
" Create${1:Resource},",
" Get${1:Resource}Params,",
" Get${1:Resource}sParams,",
" ${1:Resource},",
" Update${1:Resource},",
"} from './types.ts';",
"import type { HttpResponse, PaginatedHttpResponse, PaginatedResponse } from 'types/http.ts';",
"import type { Options } from 'types/request-building-options.ts';",
"import type { RequestHandler } from 'core/request-handler.ts';",
"",
"/**",
" * Provides access to the ${2:${1/(.*)/${1:/downcase}/}}s endpoints of the xMatters API.",
" * Use this class to manage ${2:${1/(.*)/${1:/downcase}/}}s, including listing, creating, updating, and deleting ${2:${1/(.*)/${1:/downcase}/}}s.",
" */",
"export class ${1:Resource}sEndpoint {",
" private readonly http: ResourceClient;",
"",
" constructor(http: RequestHandler) {",
" this.http = new ResourceClient(http, '/${3:${1/(.*)/${1:/downcase}/}}s');",
" }",
"",
" /**",
" * Get a list of ${2:${1/(.*)/${1:/downcase}/}}s from xMatters.",
" * The results can be filtered and paginated using the options object.",
" *",
" * @param options Optional parameters including query filters, headers, and other request options",
" * @returns The HTTP response containing a paginated list of ${2:${1/(.*)/${1:/downcase}/}}s",
" * @throws {XmApiError} If the request fails",
" */",
" get(",
" options?: Options & { query?: Get${1:Resource}sParams },",
" ): Promise<PaginatedHttpResponse<${1:Resource}>> {",
" return this.http.get<PaginatedResponse<${1:Resource}>>(options);",
" }",
"",
" /**",
" * Get a ${2:${1/(.*)/${1:/downcase}/}} by its ID or targetName.",
" *",
" * @param identifier The ID or targetName of the ${2:${1/(.*)/${1:/downcase}/}} to retrieve",
" * @param options Optional request options including embed parameters and headers",
" * @returns The HTTP response containing the ${2:${1/(.*)/${1:/downcase}/}}",
" * @throws {XmApiError} If the request fails",
" */",
" getByIdentifier(",
" identifier: string,",
" options?: Options & { query?: Get${1:Resource}Params },",
" ): Promise<HttpResponse<${1:Resource}>> {",
" return this.http.get<${1:Resource}>({ ...options, path: identifier });",
" }",
"",
" /**",
" * Create a new ${2:${1/(.*)/${1:/downcase}/}} or update an existing one",
" *",
" * @param ${2:${1/(.*)/${1:/downcase}/}} The ${2:${1/(.*)/${1:/downcase}/}} to create or update",
" * @param options Optional request options such as custom headers",
" * @returns The HTTP response containing the created or updated ${2:${1/(.*)/${1:/downcase}/}}",
" * @throws {XmApiError} If the request fails",
" */",
" save(",
" ${2:${1/(.*)/${1:/downcase}/}}: Create${1:Resource} | Update${1:Resource},",
" options?: Options,",
" ): Promise<HttpResponse<${1:Resource}>> {",
" return this.http.post<${1:Resource}>({ ...options, body: ${2:${1/(.*)/${1:/downcase}/}} });",
" }",
"",
" /**",
" * Delete a ${2:${1/(.*)/${1:/downcase}/}} by ID",
" *",
" * @param id The ID of the ${2:${1/(.*)/${1:/downcase}/}} to delete",
" * @param options Optional request options such as custom headers",
" * @returns The HTTP response",
" * @throws {XmApiError} If the request fails",
" */",
" delete(id: string, options?: Options): Promise<HttpResponse<${1:Resource}>> {",
" return this.http.delete<${1:Resource}>({ ...options, path: id });",
" }",
"}",
"$0"
]
}
}
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 J. Friedrich

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading