Skip to content

Commit

Permalink
🔧 fix: give Windsurf a crack at dealing with JSR's restrictions (afte…
Browse files Browse the repository at this point in the history
…r providing a hint)
  • Loading branch information
masonmark committed Dec 14, 2024
1 parent ebf100b commit 161b020
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 23 deletions.
6 changes: 5 additions & 1 deletion AlphabeticOrUnderscoreOrHyphenString.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { ValidatedString } from './ValidatedString.ts';
const isAlphabeticOrUnderscoreOrHyphen = (s: string) => /^[a-zA-Z_-]+$/.test(s);

const { factory, type } = ValidatedString.create(
// Why JSRCompatibleFactory? See https://github.com/axhxrx/validated-string/issues/1
const JSRCompatibleFactory = ValidatedString.create(
isAlphabeticOrUnderscoreOrHyphen,
{
name: 'AlphabeticOrUnderscoreOrHyphenString',
description: 'must contain only letters (A-Z, a-z), underscores, or hyphens',
},
);

const type = JSRCompatibleFactory.type;
const factory = JSRCompatibleFactory.factory;

export type AlphabeticOrUnderscoreOrHyphenString = typeof type;
export const AlphabeticOrUnderscoreOrHyphenString = factory;
6 changes: 3 additions & 3 deletions AlphabeticOrUnderscoreString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { ValidatedString } from './ValidatedString.ts';

const isAlphabeticOrUnderscore = (s: string): boolean => /^[a-zA-Z_]+$/.test(s);

const { factory, type } = ValidatedString.create(isAlphabeticOrUnderscore, {
const JSRCompatibleFactory = ValidatedString.create(isAlphabeticOrUnderscore, {
name: 'AlphabeticOrUnderscoreString',
description: 'must contain only letters (A-Z, a-z) or underscores',
});

export type AlphabeticOrUnderscoreString = typeof type;
export const AlphabeticOrUnderscoreString = factory;
export type AlphabeticOrUnderscoreString = typeof JSRCompatibleFactory.type;
export const AlphabeticOrUnderscoreString = JSRCompatibleFactory.factory;
6 changes: 3 additions & 3 deletions AlphabeticString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { ValidatedString } from './ValidatedString.ts';

const isAlphabetic = (s: string): boolean => /^[a-zA-Z]+$/.test(s);

const { factory, type } = ValidatedString.create(isAlphabetic, {
const JSRCompatibleFactory = ValidatedString.create(isAlphabetic, {
name: 'AlphabeticString',
description: 'must contain only letters (A-Z, a-z)',
});

export type AlphabeticString = typeof type;
export const AlphabeticString = factory;
export type AlphabeticString = typeof JSRCompatibleFactory.type;
export const AlphabeticString = JSRCompatibleFactory.factory;
7 changes: 4 additions & 3 deletions AwesomeString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { ValidatedString } from './ValidatedString.ts';

const isAwesome = (s: string): boolean => s === 'awesome';

const { factory, type } = ValidatedString.create(isAwesome);
export type AwesomeString = typeof type;
export const AwesomeString = factory;
const JSRCompatibleFactory = ValidatedString.create(isAwesome);

export type AwesomeString = typeof JSRCompatibleFactory.type;
export const AwesomeString = JSRCompatibleFactory.factory;

// Usage:
const x = AwesomeString.try('awesome'); // AwesomeString | undefined
Expand Down
2 changes: 1 addition & 1 deletion LowercaseAlphabeticString.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Deno.test('LowercaseAlphabeticString - assert throws with descriptive message',
assertThrows(
() => LowercaseAlphabeticString.assert('Hello123!'),
Error,
'Invalid string did not pass validation: Supplied value "Hello123!" is not valid for validator "LowercaseAlphabeticString" (must contain only lowercase letters a-z).',
'Invalid string did not pass validation: Supplied value "Hello123!" is not valid for validator "LowercaseAlphabeticString" (must contain only lowercase letters (a-z)).',
);
});

Expand Down
8 changes: 4 additions & 4 deletions LowercaseAlphabeticString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { ValidatedString } from './ValidatedString.ts';

const isLowercaseAlpha = (s: string): boolean => /^[a-z]+$/.test(s);

const { factory, type } = ValidatedString.create(isLowercaseAlpha, {
const JSRCompatibleFactory = ValidatedString.create(isLowercaseAlpha, {
name: 'LowercaseAlphabeticString',
description: 'must contain only lowercase letters a-z',
description: 'must contain only lowercase letters (a-z)',
});

export type LowercaseAlphabeticString = typeof type;
export const LowercaseAlphabeticString = factory;
export type LowercaseAlphabeticString = typeof JSRCompatibleFactory.type;
export const LowercaseAlphabeticString = JSRCompatibleFactory.factory;
6 changes: 3 additions & 3 deletions PrometheusMetricName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { ValidatedString } from './ValidatedString.ts';

const isPrometheusMetricName = (s: string): boolean => /^[a-zA-Z_:][a-zA-Z0-9_:]*$/.test(s);

const { factory, type } = ValidatedString.create(isPrometheusMetricName, {
const JSRCompatibleFactory = ValidatedString.create(isPrometheusMetricName, {
name: 'PrometheusMetricName',
description: 'must start with a letter, underscore, or colon, followed by letters, digits, underscores, or colons',
});

/**
A validated string that represents a Prometheus metric name. See {@link ValidatedString} for more information. Note that this might not really exactly match the rules for Prometheus metric names, but it's close enough for our purposes; namely, generating metrics — don't rely on this to *validate* Prometheus metric names, as it is based on a quick skim of the Prometheus docs.
*/
export type PrometheusMetricName = typeof type;
export const PrometheusMetricName = factory;
export type PrometheusMetricName = typeof JSRCompatibleFactory.type;
export const PrometheusMetricName = JSRCompatibleFactory.factory;
6 changes: 3 additions & 3 deletions PrometheusMetricNameWithoutColon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { ValidatedString } from './ValidatedString.ts';

const isPrometheusMetricNameWithoutColon = (s: string): boolean => /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(s);

const { factory, type } = ValidatedString.create(
const JSRCompatibleFactory = ValidatedString.create(
isPrometheusMetricNameWithoutColon,
{
name: 'PrometheusMetricNameWithoutColon',
description: 'must start with a letter or underscore, followed by letters, digits, or underscores',
},
);

export type PrometheusMetricNameWithoutColon = typeof type;
export const PrometheusMetricNameWithoutColon = factory;
export type PrometheusMetricNameWithoutColon = typeof JSRCompatibleFactory.type;
export const PrometheusMetricNameWithoutColon = JSRCompatibleFactory.factory;
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# @axhxrx/validated-strings

A library to help make runtime-validated strings, while still preserving a modicum of type-safety at build-time. Intended for specialized string types that are too complex to be modeled within the type system itself, e.g. "starts with an alphanumeric character and less than 1000 characters long, with at least three swear words", or "three words in German, separated by spaces", etc.
A library to help make runtime-validated strings, but using branded types to preserve a modicum of type-safety and convenience at build-time.

Intended for specialized string types that are too complex to be modeled within the type system itself, e.g. "starts with an alphanumeric character and less than 1000 characters long, with at least three swear words", or "three words in German, separated by spaces", etc.

Example:

Expand All @@ -23,7 +25,7 @@ export type CowName = typeof type;
const x = CowName.try('Bessie'); // x is 'Bessie'
const y: CowName | undefined = CowName.try('not a cow name'); // y is undefined
const z: CowName = CowName.assert('Bessie'); // z is 'Bessie'
const ohFuck: never = CowName.assert('not a cow name'); // throws an error
const ohFuck = CowName.assert('not a cow name'); // throws an error
```

That's useful when you want to worry about the validation only in one spot, and lean on the type system elsewhere. E.g.:
Expand Down

0 comments on commit 161b020

Please sign in to comment.