diff --git a/README.md b/README.md index ebcf88b..e25eff2 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,39 @@ -[![Develop branch](https://github.com/openbeta/climbing-grades/actions/workflows/nodejs.yml/badge.svg?branch=develop)](https://github.com/OpenBeta/climbing-grades/actions/workflows/nodejs.yml?query=develop) [![License](https://img.shields.io/github/license/openbeta/climbing-grades?style=flat-square)](./LICENSE) +[![Develop branch](https://github.com/openbeta/climbing-grades/actions/workflows/nodejs.yml/badge.svg?branch=develop)](https://github.com/OpenBeta/climbing-grades/actions/workflows/nodejs.yml?query=develop) [![License](https://img.shields.io/github/license/openbeta/climbing-grades?style=flat-square)](./LICENSE) + + [![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-) + + # What is this? -Javascript utilities for working with rock climbing grades. +Typescript utilities for working with rock climbing grades. ### Supported systems **Sport & Traditional climbing** + - [x] Yosemite Decimal System - [x] French - [x] UIAA - [x] Ewbanks - [x] Saxon - [x] Brazilian +- [x] Norwegian **Bouldering** + - [x] Vermin (V-scale) - [x] Fontainebleau **Aid** + - [x] A# & C# -- [ ] Aid with mandatory free climbing (5.8 A0, etc) +- [ ] Aid with mandatory free climbing (5.8 A0, etc) **Ice** + - [x] Winter Ice (WI#) - [x] Alpine Ice (AI#) @@ -33,102 +42,102 @@ Javascript utilities for working with rock climbing grades. Code contributions are most welcome! ### Questions? -Join us on [Discord](https://discord.gg/fY9DbRav8h). ---- +Join us on [Discord](https://discord.gg/fY9DbRav8h). -### How to use the library +## How to use the library -#### Install the package +### Install the package Using NPM ``` npm install @openbeta/sandbag ``` + Using Yarn + ``` yarn add @openbeta/sandbag ``` -#### Sample Usage +### Sample Usage -- Convert Grades to Scores +#### Convert Grades to Scores -```javascript -import { French, YosemiteDecimal } from '@openbeta/sandbag' +```typescript +import { French, YosemiteDecimal } from "@openbeta/sandbag"; -const score = French.getScore('8a') // Output [ 84, 85 ] +const score = French.getScore("8a"); // Output [ 84, 85 ] // Support slash grade -const slashGradeScore=French.getScore('7c+/8a') // Output [ 83, 84 ] +const slashGradeScore = French.getScore("7c+/8a"); // Output [ 83, 84 ] // Accept +/- modifier -const plusGrade= YosemiteDecimal.getScore('5.12+') // Output [ 79, 80 ] +const plusGrade = YosemiteDecimal.getScore("5.12+"); // Output [ 79, 80 ] ``` -- Convert Scores to Grades +#### Convert Scores to Grades -```javascript -import { Font } from '@openbeta/sandbag' +```typescript +import { Font } from "@openbeta/sandbag"; // Single score provided -Font.getGrade(80) // Output '7c' - -// Support a range of scores -Font.getGrade([79,81]) // Output'7b+/7c' +Font.getGrade(80); // Output '7c' +// Support a range of scores +Font.getGrade([79, 81]); // Output'7b+/7c' ``` -- Validate Grading Scales -``` javascript -import { VScale , Font }from '@openbeta/sandbag' +#### Validate Grading Scales -console.log('Is 6A a V Scale?',VScale.isType('6A')) // Output false -console.log('Is 6A a Font Scale?',Font.isType('6A')) // Output true +```typescript +import { VScale, Font } from "@openbeta/sandbag"; +console.log("Is 6A a V Scale?", VScale.isType("6A")); // Output false +console.log("Is 6A a Font Scale?", Font.isType("6A")); // Output true ``` -- Convert Grades Across Scales +#### Convert Grades Across Scales -``` javascript -import {convertGrade , GradeScales }from '@openbeta/sandbag' +```typescript +import { convertGrade, GradeScales } from "@openbeta/sandbag"; -const ydsInFrench=convertGrade('5.11a',GradeScales.YDS,GradeScales.FRENCH) // Output '6b+/6c' +const ydsInFrench = convertGrade("5.11a", GradeScales.YDS, GradeScales.FRENCH); // Output '6b+/6c' -const fontInVScale=convertGrade('6a',GradeScales.FONT,GradeScales.VSCALE) //OutPut 'V3' +const fontInVScale = convertGrade("6a", GradeScales.FONT, GradeScales.VSCALE); //OutPut 'V3' // Conversions across different disciplines are not allowed -const sportToBoulder=convertGrade('5.11a',GradeScales.YDS,GradeScales.VSCALE) +const sportToBoulder = convertGrade( + "5.11a", + GradeScales.YDS, + GradeScales.VSCALE, +); // Output: Scale: Yosemite Decimal System doesn't support converting to Scale: V Scale // '' ``` -- Get Gradeband +#### Get Gradeband -```javascript -import { Ewbank } from '@openbeta/sandbag' - -Ewbank.getGradeBand('10') // Output: 'beginner' -Ewbank.getGradeBand('30') // Output: 'expert' -Ewbank.getGradeBand('6a') // Output: Unexpected grade format: 6a for grade scale Ewbank 'unknown' +```typescript +import { Ewbank } from "@openbeta/sandbag"; +Ewbank.getGradeBand("10"); // Output: 'beginner' +Ewbank.getGradeBand("30"); // Output: 'expert' +Ewbank.getGradeBand("6a"); // Output: Unexpected grade format: 6a for grade scale Ewbank 'unknown' ``` -- Compare Grades - -```javascript -import { French, YosemiteDecimal } from '@openbeta/sandbag' +#### Compare Grades -const harder = French.getScore('8a') // Output: [ 84, 85 ] -const easier = YosemiteDecimal.getScore('5.13a') // Output: [ 82, 83 ] +```typescript +import { French, YosemiteDecimal } from "@openbeta/sandbag"; -console.log('Is 8a harder than 5.13a?',harder > easier) // Output: true +const harder = French.getScore("8a"); // Output: [ 84, 85 ] +const easier = YosemiteDecimal.getScore("5.13a"); // Output: [ 82, 83 ] +console.log("Is 8a harder than 5.13a?", harder > easier); // Output: true ``` - - See [unit tests](./src/__tests__) for more examples. ### Development (TBD) @@ -153,9 +162,11 @@ file:///Users//sandbag/coverage/lcov-report/index.html ``` #### How to publish a new release to NPM + Submit a PR with commit message `[npm publish]` ### Project Maintainers + - [Nathan Musoke](https://github.com/musoke) - [Viet Nguyen](https://github.com/vnugent) diff --git a/package.json b/package.json index 7572d8e..f118bd8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,10 @@ "name": "@openbeta/sandbag", "version": "0.0.55", "description": "Rock climbing grades and conversions", - "repository": "https://github.com/OpenBeta/sandbag.git", + "repository": { + "type": "git", + "url": "git+https://github.com/OpenBeta/sandbag.git" + }, "module": "./dist/sandbag.esm.js", "main": "./dist/index.js", "exports": { diff --git a/src/GradeParser.ts b/src/GradeParser.ts index af2da6e..7e1865f 100644 --- a/src/GradeParser.ts +++ b/src/GradeParser.ts @@ -67,6 +67,9 @@ export const convertGrade = ( return toScale.getGrade(toScore) } +/** + * @deprecated use VScale.isType instead + */ export const isVScale = (grade: string): boolean => { const scale = scales[GradeScales.VSCALE] if (scale == null) { diff --git a/src/GradeScale.ts b/src/GradeScale.ts index 63f51aa..be790cb 100644 --- a/src/GradeScale.ts +++ b/src/GradeScale.ts @@ -3,14 +3,21 @@ import { GradeBandTypes } from './GradeBands' export type Tuple = [number, number] export default interface GradeScale { + /** Return true if the passed string is a valid grade for this scale */ isType: (grade: string) => boolean + /** Convert a grade to a difficult score or score range */ getScore: (grade: string) => number | Tuple + /** Convert a difficulty score or score range to a grade */ getGrade: (score: number | Tuple) => string + /** Return the difficulty band for this grade, e.g. "beginner" */ getGradeBand: (grade: string) => GradeBandTypes + /** Human-readable name of this rating scale */ displayName: string + /** Slug name of this rating scale */ name: GradeScalesTypes offset: number conversionGroup: ConversionGroupsTypes + /** List of all grades in this scale */ grades: string[] } diff --git a/src/index.ts b/src/index.ts index a0cec2c..5c49084 100644 --- a/src/index.ts +++ b/src/index.ts @@ -80,6 +80,9 @@ const BRITISH_ADJ_ARRAY = [ 'E11' ] as const +/** + * @deprecated grades can now be accessed as a property of each GradeScale + */ const YDS_ARRAY = [ '5.0', '5.1', @@ -117,6 +120,9 @@ const YDS_ARRAY = [ '5.15d' ] +/** + * @deprecated grades can now be accessed as a property of each GradeScale + */ const FRENCH_ARRAY = [ '1a', '1b', @@ -162,6 +168,9 @@ const FRENCH_ARRAY = [ '9c+' ] +/** + * @deprecated grades can now be accessed as a property of each GradeScale + */ const UIAA_ARRAY = [ '1', '2', @@ -192,6 +201,9 @@ const UIAA_ARRAY = [ '12' ] +/** + * @deprecated grades can now be accessed as a property of each GradeScale + */ const EWBANK_ARRAY = [ '1', '2', @@ -235,6 +247,9 @@ const EWBANK_ARRAY = [ '40' ] +/** + * @deprecated grades can now be accessed as a property of each GradeScale + */ const SAXON_ARRAY = [ '1', '2', @@ -261,6 +276,9 @@ const SAXON_ARRAY = [ '12b' ] +/** + * @deprecated grades can now be accessed as a property of each GradeScale + */ const NORWAY_ARRAY = [ '1-', '1', @@ -301,7 +319,7 @@ const NORWAY_ARRAY = [ ] /** - * @deprecated - grades can now be accessed as a property of each GradeScale + * @deprecated grades can now be accessed as a property of each GradeScale */ export const freeClimbing = { clean: { diff --git a/tsconfig.json b/tsconfig.json index f9bda8e..cbcbb7e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,28 +1,24 @@ { "compilerOptions": { - "types": ["node", "jest"], - "allowJs": true, - "skipLibCheck": true, - "target": "ES6", - "module": "ESNext", - "esModuleInterop": true, - "resolveJsonModule": true, - "moduleResolution": "Node", - "rootDir": "./src", - "outDir": "build", - "sourceMap": true, - "strictNullChecks": true, - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "declaration": true - }, - "ts-node":{ - "esm":true, - "experimentalSpecifierResolution": "node", - + "types": ["node", "jest"], + "allowJs": true, + "skipLibCheck": true, + "target": "ES6", + "module": "ESNext", + "esModuleInterop": true, + "resolveJsonModule": true, + "moduleResolution": "Node", + "rootDir": "./src", + "outDir": "build", + "sourceMap": true, + "strictNullChecks": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "declaration": true }, - "include": [ - ".ts", - "src/**/*.ts" - ], -} \ No newline at end of file + "ts-node": { + "esm": true, + "experimentalSpecifierResolution": "node" + }, + "include": [".ts", "src/**/*.ts"] +}