@o-zone/scorer-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -0
- package/dist/auth.d.ts +5 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +148 -0
- package/dist/auth.js.map +1 -0
- package/dist/competition/index.d.ts +7 -0
- package/dist/competition/index.d.ts.map +1 -0
- package/dist/competition/index.js +10 -0
- package/dist/competition/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/race/index.d.ts +7 -0
- package/dist/race/index.d.ts.map +1 -0
- package/dist/race/index.js +10 -0
- package/dist/race/index.js.map +1 -0
- package/dist/router.d.ts +3 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +46 -0
- package/dist/router.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +13 -0
- package/dist/server.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# @o-zone/scorer-core
|
|
2
|
+
|
|
3
|
+
Orienteering scoring core library with modular exports for server, race, and competition management.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @o-zone/scorer-core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Server Module
|
|
14
|
+
```typescript
|
|
15
|
+
import { Scorer } from '@o-zone/scorer-core/server';
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Race Module
|
|
19
|
+
```typescript
|
|
20
|
+
import { ... } from '@o-zone/scorer-core/race';
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Competition Module
|
|
24
|
+
```typescript
|
|
25
|
+
import { ... } from '@o-zone/scorer-core/competition';
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Development
|
|
29
|
+
|
|
30
|
+
### Setup
|
|
31
|
+
```bash
|
|
32
|
+
bun install
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Build
|
|
36
|
+
```bash
|
|
37
|
+
bun run build # Compile TypeScript → dist/
|
|
38
|
+
bun run build:watch # Watch mode for development
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Quality Checks
|
|
42
|
+
```bash
|
|
43
|
+
bun run check:types # TypeScript type checking
|
|
44
|
+
bun run lint # Code quality with Biome
|
|
45
|
+
bun run lint:fix # Auto-fix lint issues
|
|
46
|
+
bun run format # Code formatting
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Publishing
|
|
50
|
+
|
|
51
|
+
This package uses [Changesets](https://github.com/changesets/changesets) for automated version management and npm publishing.
|
|
52
|
+
|
|
53
|
+
### Workflow
|
|
54
|
+
1. Make code changes
|
|
55
|
+
2. Run `bun changeset add` to document changes
|
|
56
|
+
3. Push to main branch
|
|
57
|
+
4. GitHub Actions automatically:
|
|
58
|
+
- Creates a Release PR (bumps version, updates changelog)
|
|
59
|
+
- Publishes to npm when PR is merged
|
|
60
|
+
|
|
61
|
+
### Documentation
|
|
62
|
+
- [Quick Reference](QUICK_REF.md) - One-page reference
|
|
63
|
+
|
|
64
|
+
## Package Structure
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
src/
|
|
68
|
+
├── server.ts # Server module
|
|
69
|
+
├── race/index.ts # Race module
|
|
70
|
+
└── competition/ # Competition module
|
|
71
|
+
|
|
72
|
+
dist/ # Built output (published to npm)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Scripts
|
|
76
|
+
|
|
77
|
+
| Command | Purpose |
|
|
78
|
+
|---------|---------|
|
|
79
|
+
| `bun run build` | Build TypeScript to dist/ |
|
|
80
|
+
| `bun run build:watch` | Watch mode build |
|
|
81
|
+
| `bun run check:types` | Type check without emit |
|
|
82
|
+
| `bun run lint` | Lint code |
|
|
83
|
+
| `bun run lint:fix` | Auto-fix lint issues |
|
|
84
|
+
| `bun run format` | Format code |
|
|
85
|
+
| `bun changeset add` | Create a changeset |
|
|
86
|
+
| `bun run publish` | Build and publish |
|
|
87
|
+
|
|
88
|
+
## Technologies
|
|
89
|
+
|
|
90
|
+
- **Language**: TypeScript 5.3+
|
|
91
|
+
- **Runtime**: Bun 1.3.5+
|
|
92
|
+
- **Package Manager**: Bun
|
|
93
|
+
- **Linter**: Biome
|
|
94
|
+
- **Release Management**: Changesets
|
|
95
|
+
- **CI/CD**: GitHub Actions
|
|
96
|
+
- **Module Format**: ES Modules (ESM)
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
MIT
|
|
101
|
+
|
|
102
|
+
## Contributing
|
|
103
|
+
|
|
104
|
+
1. Create a feature branch
|
|
105
|
+
2. Make your changes
|
|
106
|
+
3. Run `bun run lint:fix` to format
|
|
107
|
+
4. Create a changeset: `bun changes`
|
|
108
|
+
5. Push and create a pull request
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAeA;;GAEG;AACH,eAAO,MAAM,YAAY,GACvB,eAAe,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,KAAK,OAAO,qBAkEb,CAAC"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
/**
|
|
3
|
+
* Check bearer authorization header. Token will be a JWT.
|
|
4
|
+
*/
|
|
5
|
+
export const authenticate = async (authorization, req) => {
|
|
6
|
+
if (!authorization) {
|
|
7
|
+
console.error('No authorization header');
|
|
8
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
9
|
+
}
|
|
10
|
+
const proto = req.headers.get('X-Forwarded-Proto') ?? 'http';
|
|
11
|
+
const host = req.headers.get('X-Forwarded-Host') ??
|
|
12
|
+
req.headers.get('Host') ??
|
|
13
|
+
'unknown-host';
|
|
14
|
+
const aud = `${proto}://${host}${new URL(req.url).pathname}`;
|
|
15
|
+
const token = authorization.startsWith('Bearer ')
|
|
16
|
+
? authorization.slice('Bearer '.length).trim()
|
|
17
|
+
: authorization.trim();
|
|
18
|
+
const parts = token.split('.');
|
|
19
|
+
if (parts.length !== 3) {
|
|
20
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
21
|
+
}
|
|
22
|
+
const [encodedHeader, encodedPayload, encodedSignature] = parts;
|
|
23
|
+
const header = parseJsonSection(encodedHeader);
|
|
24
|
+
const payload = parseJsonSection(encodedPayload);
|
|
25
|
+
const iss = typeof payload.iss === 'string' ? payload.iss : null;
|
|
26
|
+
const kid = typeof header.kid === 'string' ? header.kid : null;
|
|
27
|
+
const alg = typeof header.alg === 'string' ? header.alg : null;
|
|
28
|
+
if (!iss || !kid || !alg) {
|
|
29
|
+
console.error('Invalid token structure');
|
|
30
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
31
|
+
}
|
|
32
|
+
if (process.env.AUTH_ALLOWED_ISSUERS &&
|
|
33
|
+
!process.env.AUTH_ALLOWED_ISSUERS.split(',')
|
|
34
|
+
.map((s) => s.trim())
|
|
35
|
+
.includes(iss)) {
|
|
36
|
+
console.error('Unauthorized issuer', iss);
|
|
37
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
38
|
+
}
|
|
39
|
+
const audienceValid = payload.aud === aud ||
|
|
40
|
+
(Array.isArray(payload.aud) && payload.aud.includes(aud));
|
|
41
|
+
if (!audienceValid) {
|
|
42
|
+
console.error('Invalid audience', payload.aud, 'expected', aud);
|
|
43
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
44
|
+
}
|
|
45
|
+
const jwk = await getJwkForIssuer(iss, kid);
|
|
46
|
+
const verified = await verifySignature(alg, jwk, `${encodedHeader}.${encodedPayload}`, encodedSignature);
|
|
47
|
+
if (!verified) {
|
|
48
|
+
console.error('Invalid signature');
|
|
49
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
};
|
|
53
|
+
const openIdConfigCache = new Map();
|
|
54
|
+
const jwksCache = new Map();
|
|
55
|
+
const cryptoKeyCache = new Map();
|
|
56
|
+
const parseJsonSection = (section) => {
|
|
57
|
+
const bytes = base64UrlToUint8Array(section);
|
|
58
|
+
const text = new TextDecoder().decode(bytes);
|
|
59
|
+
return JSON.parse(text);
|
|
60
|
+
};
|
|
61
|
+
const base64UrlToUint8Array = (input) => {
|
|
62
|
+
const normalized = input.replace(/-/g, '+').replace(/_/g, '/');
|
|
63
|
+
const padded = normalized.padEnd(normalized.length + ((4 - (normalized.length % 4)) % 4), '=');
|
|
64
|
+
return Uint8Array.from(Buffer.from(padded, 'base64'));
|
|
65
|
+
};
|
|
66
|
+
const getOpenIdConfig = async (issuer) => {
|
|
67
|
+
const cached = openIdConfigCache.get(issuer);
|
|
68
|
+
if (cached) {
|
|
69
|
+
return cached;
|
|
70
|
+
}
|
|
71
|
+
const configUrl = new URL('.well-known/openid-configuration', issuer.endsWith('/') ? issuer : `${issuer}/`);
|
|
72
|
+
const res = await fetch(configUrl);
|
|
73
|
+
if (!res.ok) {
|
|
74
|
+
console.error('Failed to fetch OpenID config');
|
|
75
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
76
|
+
}
|
|
77
|
+
const json = (await res.json());
|
|
78
|
+
if (!json.jwks_uri) {
|
|
79
|
+
console.error('Invalid OpenID config');
|
|
80
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
81
|
+
}
|
|
82
|
+
openIdConfigCache.set(issuer, json.jwks_uri);
|
|
83
|
+
return json.jwks_uri;
|
|
84
|
+
};
|
|
85
|
+
const getJwkForIssuer = async (issuer, kid) => {
|
|
86
|
+
const jwksUri = await getOpenIdConfig(issuer);
|
|
87
|
+
const cachedKeys = jwksCache.get(jwksUri);
|
|
88
|
+
if (cachedKeys) {
|
|
89
|
+
const key = cachedKeys.find((k) => k.kid === kid);
|
|
90
|
+
if (key) {
|
|
91
|
+
return key;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const res = await fetch(jwksUri);
|
|
95
|
+
if (!res.ok) {
|
|
96
|
+
console.error('Failed to fetch JWKS');
|
|
97
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
98
|
+
}
|
|
99
|
+
const json = (await res.json());
|
|
100
|
+
if (!json.keys?.length) {
|
|
101
|
+
console.error('Invalid JWKS');
|
|
102
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
103
|
+
}
|
|
104
|
+
jwksCache.set(jwksUri, json.keys);
|
|
105
|
+
const key = json.keys.find((k) => k.kid === kid);
|
|
106
|
+
if (!key) {
|
|
107
|
+
console.error('JWK not found for kid', kid);
|
|
108
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
109
|
+
}
|
|
110
|
+
return key;
|
|
111
|
+
};
|
|
112
|
+
const verifySignature = async (alg, jwk, signingInput, encodedSignature) => {
|
|
113
|
+
const cryptoAlg = getCryptoAlgorithm(alg, jwk);
|
|
114
|
+
const cacheKey = `${jwk.kid}:${jwk.x5t ?? ''}:${jwk.n ?? ''}`;
|
|
115
|
+
let cryptoKey = cryptoKeyCache.get(cacheKey);
|
|
116
|
+
if (!cryptoKey) {
|
|
117
|
+
cryptoKey = await crypto.subtle.importKey('jwk', jwk, cryptoAlg, false, [
|
|
118
|
+
'verify',
|
|
119
|
+
]);
|
|
120
|
+
cryptoKeyCache.set(cacheKey, cryptoKey);
|
|
121
|
+
}
|
|
122
|
+
const data = new TextEncoder().encode(signingInput);
|
|
123
|
+
const signature = base64UrlToUint8Array(encodedSignature);
|
|
124
|
+
return crypto.subtle.verify(cryptoAlg, cryptoKey, signature, data);
|
|
125
|
+
};
|
|
126
|
+
const getCryptoAlgorithm = (alg, jwk) => {
|
|
127
|
+
if (alg === 'RS256') {
|
|
128
|
+
return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' };
|
|
129
|
+
}
|
|
130
|
+
if (alg === 'RS384') {
|
|
131
|
+
return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-384' };
|
|
132
|
+
}
|
|
133
|
+
if (alg === 'RS512') {
|
|
134
|
+
return { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-512' };
|
|
135
|
+
}
|
|
136
|
+
if (alg === 'ES256') {
|
|
137
|
+
return { name: 'ECDSA', hash: 'SHA-256', namedCurve: jwk.crv };
|
|
138
|
+
}
|
|
139
|
+
if (alg === 'ES384') {
|
|
140
|
+
return { name: 'ECDSA', hash: 'SHA-384', namedCurve: jwk.crv };
|
|
141
|
+
}
|
|
142
|
+
if (alg === 'ES512') {
|
|
143
|
+
return { name: 'ECDSA', hash: 'SHA-512', namedCurve: jwk.crv };
|
|
144
|
+
}
|
|
145
|
+
console.error('Unsupported algorithm', alg);
|
|
146
|
+
throw new Response('Unauthorized', { status: 401 });
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAerC;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,aAAwC,EACxC,GAAY,EACZ,EAAE;IACF,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACzC,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,MAAM,CAAC;IAC7D,MAAM,IAAI,GACR,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QACnC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;QACvB,cAAc,CAAC;IACjB,MAAM,GAAG,GAAG,GAAG,KAAK,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;IAE7D,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,SAAS,CAAC;QAC/C,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE;QAC9C,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAA6B,CAAC;IAC3D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,CAAC,aAAa,EAAE,cAAc,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC;IAChE,MAAM,MAAM,GAAG,gBAAgB,CAA0B,aAAa,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,gBAAgB,CAA0B,cAAc,CAAC,CAAC;IAE1E,MAAM,GAAG,GAAG,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACjE,MAAM,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/D,MAAM,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAE/D,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACzC,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,IACE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAChC,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC;aACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,QAAQ,CAAC,GAAG,CAAC,EAChB,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;QAC1C,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,aAAa,GACjB,OAAO,CAAC,GAAG,KAAK,GAAG;QACnB,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5D,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAChE,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,eAAe,CACpC,GAAG,EACH,GAAG,EACH,GAAG,aAAa,IAAI,cAAc,EAAE,EACpC,gBAAgB,CACjB,CAAC;IACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACnC,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;AACpD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;AAClD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAqB,CAAC;AAEpD,MAAM,gBAAgB,GAAG,CAAI,OAAe,EAAK,EAAE;IACjD,MAAM,KAAK,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,KAAa,EAAE,EAAE;IAC9C,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAC9B,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EACvD,GAAG,CACJ,CAAC;IACF,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;IAC/C,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,kCAAkC,EAClC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAC7C,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC/C,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0B,CAAC;IACzD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACvC,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,KAAK,EAAE,MAAc,EAAE,GAAW,EAAE,EAAE;IAC5D,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;QAClD,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACtC,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAE7B,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC9B,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAElC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;QAC5C,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,KAAK,EAC3B,GAAW,EACX,GAAe,EACf,YAAoB,EACpB,gBAAwB,EACxB,EAAE;IACF,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;IAE9D,IAAI,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE;YACtE,QAAQ;SACT,CAAC,CAAC;QACH,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;AACrE,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,GAAW,EAAE,GAAe,EAAE,EAAE;IAC1D,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IACjE,CAAC;IACD,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IACjE,CAAC;IACD,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;IACjE,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/competition/index.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAEhB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAM3E"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Competition module exports
|
|
2
|
+
// Add your competition-related types and functions here
|
|
3
|
+
export function createCompetition(name, season) {
|
|
4
|
+
return {
|
|
5
|
+
id: Math.random().toString(36).substring(7),
|
|
6
|
+
name,
|
|
7
|
+
season,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/competition/index.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,wDAAwD;AASxD,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,MAAc;IAC5D,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3C,IAAI;QACJ,MAAM;KACP,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC7E,cAAc,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,OAAO,EAAE,UAAU,EAAa,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAoB,MAAM,wBAAwB,CAAC;AAC7E,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/race/index.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,IAAI,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;CAEZ,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAMzD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/race/index.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,iDAAiD;AASjD,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,IAAU;IACjD,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAC3C,IAAI;QACJ,IAAI;KACL,CAAC;AACJ,CAAC"}
|
package/dist/router.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE/D,eAAO,MAAM,MAAM,GAEf,QAAQ,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,KACnC,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAoCtC,CAAC"}
|
package/dist/router.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { authenticate } from './auth';
|
|
2
|
+
const verify = async (req) => {
|
|
3
|
+
const token = req.headers.get('O-Zone-Endpoint-Verification');
|
|
4
|
+
if (!token) {
|
|
5
|
+
return new Response('Unauthorized', { status: 401 });
|
|
6
|
+
}
|
|
7
|
+
return new Response('Verify', {
|
|
8
|
+
headers: { 'O-Zone-Endpoint-Verification-Response': token },
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
export const router = (routes) => async (req) => {
|
|
12
|
+
try {
|
|
13
|
+
const authorization = req.headers.get('Authorization');
|
|
14
|
+
await authenticate(authorization, req);
|
|
15
|
+
switch (req.method) {
|
|
16
|
+
case 'OPTIONS':
|
|
17
|
+
return new Response(null, {
|
|
18
|
+
headers: {
|
|
19
|
+
'Access-Control-Allow-Origin': 'null',
|
|
20
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
21
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization, O-Zone-Endpoint-Verification',
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
case 'GET':
|
|
25
|
+
return verify(req);
|
|
26
|
+
case 'POST': {
|
|
27
|
+
const url = new URL(req.url);
|
|
28
|
+
const routeHandler = routes[url.pathname];
|
|
29
|
+
if (routeHandler) {
|
|
30
|
+
return routeHandler(req);
|
|
31
|
+
}
|
|
32
|
+
return new Response('Not Found', { status: 404 });
|
|
33
|
+
}
|
|
34
|
+
default:
|
|
35
|
+
return new Response('Method Not Allowed', { status: 405 });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
if (err instanceof Response) {
|
|
40
|
+
return err;
|
|
41
|
+
}
|
|
42
|
+
console.error('Internal server error', err);
|
|
43
|
+
return new Response('Internal Server Error', { status: 500 });
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,MAAM,GAAG,KAAK,EAAE,GAAY,EAAE,EAAE;IACpC,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC9D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE;QAC5B,OAAO,EAAE,EAAE,uCAAuC,EAAE,KAAK,EAAE;KAC5D,CAAC,CAAC;AACL,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,MAAM,GACjB,CACE,MAAoC,EACG,EAAE,CAC3C,KAAK,EAAE,GAAY,EAAE,EAAE;IACrB,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACvD,MAAM,YAAY,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QAEvC,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;YACnB,KAAK,SAAS;gBACZ,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;oBACxB,OAAO,EAAE;wBACP,6BAA6B,EAAE,MAAM;wBACrC,8BAA8B,EAAE,oBAAoB;wBACpD,8BAA8B,EAC5B,2DAA2D;qBAC9D;iBACF,CAAC,CAAC;YACL,KAAK,KAAK;gBACR,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;YACrB,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC7B,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAC1C,IAAI,YAAY,EAAE,CAAC;oBACjB,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;gBAC3B,CAAC;gBACD,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACpD,CAAC;YACD;gBACE,OAAO,IAAI,QAAQ,CAAC,oBAAoB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;YAC5B,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;QAC5C,OAAO,IAAI,QAAQ,CAAC,uBAAuB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAKxD,yBAAiB,MAAM,CAAC;IACf,MAAM,KAAK,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,SAOzD,CAAC;CACH;AAED,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { router } from './router.js';
|
|
2
|
+
const getPort = () => process.env.PORT ? Number.parseInt(process.env.PORT, 10) : 3000;
|
|
3
|
+
export var Scorer;
|
|
4
|
+
(function (Scorer) {
|
|
5
|
+
Scorer.serve = (routes) => {
|
|
6
|
+
const server = Bun.serve({
|
|
7
|
+
port: getPort(),
|
|
8
|
+
fetch: router(routes),
|
|
9
|
+
});
|
|
10
|
+
console.info(`Listening on ${server.url}`);
|
|
11
|
+
};
|
|
12
|
+
})(Scorer || (Scorer = {}));
|
|
13
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,aAAa,CAAC;AAExD,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAElE,MAAM,KAAW,MAAM,CAStB;AATD,WAAiB,MAAM;IACR,YAAK,GAAG,CAAC,MAAoC,EAAE,EAAE;QAC5D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC;YACvB,IAAI,EAAE,OAAO,EAAE;YACf,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;SACtB,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7C,CAAC,CAAC;AACJ,CAAC,EATgB,MAAM,KAAN,MAAM,QAStB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@o-zone/scorer-core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Orienteering scoring core library with modular exports",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/orienteering-nz/scorer-core"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"exports": {
|
|
12
|
+
"./server": {
|
|
13
|
+
"import": "./dist/server.js",
|
|
14
|
+
"types": "./dist/server.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./race": {
|
|
17
|
+
"import": "./dist/race/index.js",
|
|
18
|
+
"types": "./dist/race/index.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"./competition": {
|
|
21
|
+
"import": "./dist/competition/index.js",
|
|
22
|
+
"types": "./dist/competition/index.d.ts"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc --project tsconfig.build.json",
|
|
30
|
+
"build:watch": "tsc --project tsconfig.build.json --watch",
|
|
31
|
+
"changes": "changeset add",
|
|
32
|
+
"changeset": "changeset",
|
|
33
|
+
"changeset:release": "changeset version && npm run build",
|
|
34
|
+
"check:types": "tsc --noEmit",
|
|
35
|
+
"format": "biome format . --write",
|
|
36
|
+
"lint": "biome check .",
|
|
37
|
+
"lint:fix": "biome check . --write",
|
|
38
|
+
"publish": "npm run build && changeset publish"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"zod": "^4.3.6"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@biomejs/biome": "^2.3.11",
|
|
45
|
+
"@changesets/changelog-github": "^0.5.0",
|
|
46
|
+
"@changesets/cli": "^2.29.8",
|
|
47
|
+
"@total-typescript/ts-reset": "^0.6.1",
|
|
48
|
+
"@types/bun": "latest",
|
|
49
|
+
"typescript": "^5.3.3"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"typescript": "^5"
|
|
53
|
+
},
|
|
54
|
+
"packageManager": "bun@1.3.5",
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public"
|
|
57
|
+
}
|
|
58
|
+
}
|