Skip to content

Commit 4b7ac95

Browse files
Deno (#1)
Set foundations that should allow blasting through adding new endpoints --------- Co-authored-by: johan <johan.friedrich@everbridge.com>
1 parent 774cf43 commit 4b7ac95

62 files changed

Lines changed: 6887 additions & 8414 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc.json

Lines changed: 0 additions & 40 deletions
This file was deleted.

.github/copilot-instructions.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
This TypeScript project, built with Deno, is a library for JavaScript developers to consume the
2+
xMatters API (aka `xmApi`).
3+
4+
### Project Priorities
5+
6+
1. **Good DX**:
7+
8+
- The library should provide a great developer experience (DX) for JavaScript and TypeScript
9+
developers who use it (consumers), and for those who develop it (maintainers).
10+
- When these 2 priorities are at odds, the library should prioritize a good DX for consumers.
11+
- It should be easy to use, with clear and concise APIs that are intuitive to understand.
12+
13+
2. **Consistency**:
14+
15+
- Code should be consistent in **style**, **structure**, and **behavior**.
16+
- Follow consistent **naming conventions**, **error handling**, and **response structures**.
17+
18+
3. **Zero Dependencies**:
19+
20+
- Do not use any third-party libraries.
21+
- Only use Deno’s standard library, and only for **unit testing**.
22+
23+
4. **Dependency Injection**:
24+
25+
- Consumers must be able to inject their own:
26+
- HTTP client
27+
- Logger
28+
- Any other external dependencies when applicable
29+
30+
5. **Type Safety**:
31+
32+
- Use TypeScript features when they add value, not just because you can.
33+
- Avoid the non-null assertion operator (`!`) entirely.
34+
- Prefer `null` over `undefined` when explicitly assigning absence of a value.
35+
36+
6. **Documentation**: The library should be well-documented, with clear examples and usage
37+
instructions.
38+
39+
### Development Guidelines
40+
41+
It should be extremely easy for the maintainers to add more endpoints in the future. The core logic
42+
of how a request is built and sent should be abstracted away from the endpoint implementations.
43+
44+
- Do not make changes until you are **95% confident** in what needs to be built.
45+
- Ask clarifying questions until you reach that level of confidence.
46+
47+
#### The Sandbox
48+
49+
- `/sandbox/index.ts` is for quick prototyping and testing.
50+
- Though version controlled, this file is **not** part of the library shipped to consumers.
51+
- Do **not** modify the sandbox unless explicitly instructed.
52+
- Must be run with:
53+
54+
```bash
55+
deno task sandbox
56+
```
57+
58+
#### Unit Tests
59+
60+
- **Never** send real HTTP requests.
61+
- Use _mocks_ or _stubs_ for all external interactions.
62+
- Must be run with:
63+
64+
```bash
65+
deno test
66+
```

.github/workflows/publishToJsr.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Publish to JSR
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*' # Triggers on version tags like v0.1.0
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Set up Deno
17+
uses: denoland/setup-deno@v1
18+
with:
19+
deno-version: v2.x
20+
21+
- name: Publish to JSR
22+
run: deno publish

.github/workflows/validation.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Build
2+
3+
on:
4+
push:
5+
branches:
6+
- '**'
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: denoland/setup-deno@v2
14+
with:
15+
deno-version: v2.x # Run with latest stable Deno.
16+
17+
- run: deno fmt --check
18+
19+
- run: deno lint
20+
21+
- run: deno test --coverage=cov/
22+
23+
# This generates a report from the collected coverage in `deno test --coverage`. It is
24+
# stored as a .lcov file which integrates well with services such as Codecov, Coveralls and Travis CI.
25+
- run: deno coverage --lcov cov/ > cov.lcov

.gitignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
node_modules/
2-
sandbox/config.json
3-
sandbox/index.js
1+
sandbox/.env
2+
dist/
3+
node_modules/

.vscode/extensions.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"recommendations": [
3+
"denoland.vscode-deno",
4+
"johanfive.fyi"
5+
]
6+
}

.vscode/settings.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"[typescript]": {
3+
"editor.defaultFormatter": "denoland.vscode-deno",
4+
"editor.formatOnSave": true
5+
},
6+
"[json]": {
7+
"editor.defaultFormatter": "denoland.vscode-deno",
8+
"editor.formatOnSave": true
9+
},
10+
"[jsonc]": {
11+
"editor.defaultFormatter": "denoland.vscode-deno",
12+
"editor.formatOnSave": true
13+
},
14+
"[yaml]": {
15+
"editor.defaultFormatter": "denoland.vscode-deno",
16+
"editor.formatOnSave": true
17+
},
18+
"deno.enable": true,
19+
"deno.lint": true
20+
}

.vscode/typescript.code-snippets

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
{
2+
"xMatters Endpoint Index": {
3+
"prefix": "xm-endpoint",
4+
"description": "Generate a complete endpoint index.ts file",
5+
"body": [
6+
"import { ResourceClient } from 'core/resource-client.ts';",
7+
"import type {",
8+
" Create${1:Resource},",
9+
" Get${1:Resource}Params,",
10+
" Get${1:Resource}sParams,",
11+
" ${1:Resource},",
12+
" Update${1:Resource},",
13+
"} from './types.ts';",
14+
"import type { HttpResponse, PaginatedHttpResponse, PaginatedResponse } from 'types/http.ts';",
15+
"import type { Options } from 'types/request-building-options.ts';",
16+
"import type { RequestHandler } from 'core/request-handler.ts';",
17+
"",
18+
"/**",
19+
" * Provides access to the ${2:${1/(.*)/${1:/downcase}/}}s endpoints of the xMatters API.",
20+
" * Use this class to manage ${2:${1/(.*)/${1:/downcase}/}}s, including listing, creating, updating, and deleting ${2:${1/(.*)/${1:/downcase}/}}s.",
21+
" */",
22+
"export class ${1:Resource}sEndpoint {",
23+
" private readonly http: ResourceClient;",
24+
"",
25+
" constructor(http: RequestHandler) {",
26+
" this.http = new ResourceClient(http, '/${3:${1/(.*)/${1:/downcase}/}}s');",
27+
" }",
28+
"",
29+
" /**",
30+
" * Get a list of ${2:${1/(.*)/${1:/downcase}/}}s from xMatters.",
31+
" * The results can be filtered and paginated using the options object.",
32+
" *",
33+
" * @param options Optional parameters including query filters, headers, and other request options",
34+
" * @returns The HTTP response containing a paginated list of ${2:${1/(.*)/${1:/downcase}/}}s",
35+
" * @throws {XmApiError} If the request fails",
36+
" */",
37+
" get(",
38+
" options?: Options & { query?: Get${1:Resource}sParams },",
39+
" ): Promise<PaginatedHttpResponse<${1:Resource}>> {",
40+
" return this.http.get<PaginatedResponse<${1:Resource}>>(options);",
41+
" }",
42+
"",
43+
" /**",
44+
" * Get a ${2:${1/(.*)/${1:/downcase}/}} by its ID or targetName.",
45+
" *",
46+
" * @param identifier The ID or targetName of the ${2:${1/(.*)/${1:/downcase}/}} to retrieve",
47+
" * @param options Optional request options including embed parameters and headers",
48+
" * @returns The HTTP response containing the ${2:${1/(.*)/${1:/downcase}/}}",
49+
" * @throws {XmApiError} If the request fails",
50+
" */",
51+
" getByIdentifier(",
52+
" identifier: string,",
53+
" options?: Options & { query?: Get${1:Resource}Params },",
54+
" ): Promise<HttpResponse<${1:Resource}>> {",
55+
" return this.http.get<${1:Resource}>({ ...options, path: identifier });",
56+
" }",
57+
"",
58+
" /**",
59+
" * Create a new ${2:${1/(.*)/${1:/downcase}/}} or update an existing one",
60+
" *",
61+
" * @param ${2:${1/(.*)/${1:/downcase}/}} The ${2:${1/(.*)/${1:/downcase}/}} to create or update",
62+
" * @param options Optional request options such as custom headers",
63+
" * @returns The HTTP response containing the created or updated ${2:${1/(.*)/${1:/downcase}/}}",
64+
" * @throws {XmApiError} If the request fails",
65+
" */",
66+
" save(",
67+
" ${2:${1/(.*)/${1:/downcase}/}}: Create${1:Resource} | Update${1:Resource},",
68+
" options?: Options,",
69+
" ): Promise<HttpResponse<${1:Resource}>> {",
70+
" return this.http.post<${1:Resource}>({ ...options, body: ${2:${1/(.*)/${1:/downcase}/}} });",
71+
" }",
72+
"",
73+
" /**",
74+
" * Delete a ${2:${1/(.*)/${1:/downcase}/}} by ID",
75+
" *",
76+
" * @param id The ID of the ${2:${1/(.*)/${1:/downcase}/}} to delete",
77+
" * @param options Optional request options such as custom headers",
78+
" * @returns The HTTP response",
79+
" * @throws {XmApiError} If the request fails",
80+
" */",
81+
" delete(id: string, options?: Options): Promise<HttpResponse<${1:Resource}>> {",
82+
" return this.http.delete<${1:Resource}>({ ...options, path: id });",
83+
" }",
84+
"}",
85+
"$0"
86+
]
87+
}
88+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 J. Friedrich
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)