@halospv3/hce.shared-config 3.0.0 → 3.1.0-develop.2
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/CHANGELOG.md +39 -6
- package/dotnet/.github/workflows/_unit_test.yml +1 -1
- package/dotnet/.github/workflows/dotnet-release.yml +1 -1
- package/dotnet/PublishAll.targets +40 -15
- package/mjs/dotnet/GitlabNugetRegistryInfo.d.ts +2 -3
- package/mjs/dotnet/GitlabNugetRegistryInfo.d.ts.map +1 -1
- package/mjs/dotnet/GitlabNugetRegistryInfo.mjs +2 -2
- package/mjs/dotnet/GitlabNugetRegistryInfo.mjs.map +1 -1
- package/mjs/dotnet/MSBuildProject.d.ts +3 -4
- package/mjs/dotnet/MSBuildProject.d.ts.map +1 -1
- package/mjs/dotnet/MSBuildProject.mjs +4 -4
- package/mjs/dotnet/MSBuildProject.mjs.map +1 -1
- package/mjs/dotnet/NugetProjectProperties.d.ts +3 -3
- package/mjs/dotnet/NugetProjectProperties.d.ts.map +1 -1
- package/mjs/dotnet/NugetRegistryInfo.d.ts +7 -7
- package/mjs/dotnet/NugetRegistryInfo.d.ts.map +1 -1
- package/mjs/dotnet/NugetRegistryInfo.mjs +4 -4
- package/mjs/dotnet/NugetRegistryInfo.mjs.map +1 -1
- package/mjs/dotnet/helpers.d.ts +2 -2
- package/mjs/dotnet/helpers.d.ts.map +1 -1
- package/mjs/eslintConfig.d.ts.map +1 -1
- package/mjs/eslintConfig.mjs +23 -58
- package/mjs/eslintConfig.mjs.map +1 -1
- package/mjs/utils/execAsync.d.ts +2 -2
- package/mjs/utils/execAsync.d.ts.map +1 -1
- package/mjs/utils/execAsync.mjs +2 -2
- package/mjs/utils/execAsync.mjs.map +1 -1
- package/mjs/utils/isError.d.ts +11 -0
- package/mjs/utils/isError.d.ts.map +1 -0
- package/mjs/utils/isError.mjs +19 -0
- package/mjs/utils/isError.mjs.map +1 -0
- package/mjs/utils/miscTypes.d.ts +1 -2
- package/mjs/utils/miscTypes.d.ts.map +1 -1
- package/package.json +8 -6
- package/src/dotnet/GitlabNugetRegistryInfo.ts +4 -5
- package/src/dotnet/MSBuildProject.ts +7 -8
- package/src/dotnet/NugetProjectProperties.ts +2 -3
- package/src/dotnet/NugetRegistryInfo.ts +11 -12
- package/src/dotnet/helpers.ts +2 -3
- package/src/eslintConfig.ts +9 -101
- package/src/utils/execAsync.ts +4 -5
- package/src/utils/isError.ts +18 -0
- package/src/utils/miscTypes.ts +1 -2
|
@@ -5,7 +5,7 @@ import type { NugetProjectProperties } from './NugetProjectProperties.js';
|
|
|
5
5
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
6
6
|
|
|
7
7
|
import { config as configDotenv } from '@dotenvx/dotenvx';
|
|
8
|
-
import { type } from 'arktype';
|
|
8
|
+
import { type, type Type } from 'arktype';
|
|
9
9
|
import { detectFile, detectFileSync } from 'chardet';
|
|
10
10
|
import { ok } from 'node:assert/strict';
|
|
11
11
|
import type { ExecException } from 'node:child_process';
|
|
@@ -15,12 +15,11 @@ import { tmpdir } from 'node:os';
|
|
|
15
15
|
import node_path from 'node:path';
|
|
16
16
|
import { cwd, env } from 'node:process';
|
|
17
17
|
import { setTimeout } from 'node:timers/promises';
|
|
18
|
-
import {
|
|
18
|
+
import { isError } from '../utils/isError.js';
|
|
19
19
|
import sanitizeFileName from 'sanitize-filename';
|
|
20
20
|
import { getEnvVarValue } from '../utils/env.js';
|
|
21
21
|
import { execAsync } from '../utils/execAsync.js';
|
|
22
22
|
import { catchCsc2012, MSBuildEvaluationOutput, MSBuildProject } from './MSBuildProject.js';
|
|
23
|
-
import type { ObjectType } from 'arktype/internal/methods/object.ts';
|
|
24
23
|
import type { Default } from 'arktype/internal/attributes.ts';
|
|
25
24
|
|
|
26
25
|
type TmpDirNamespace_Unix = `${ReturnType<typeof tmpdir>}/HCE.Shared/.NET/Dummies`;
|
|
@@ -49,7 +48,7 @@ export async function getGithubOutput(): Promise<ReturnType<typeof configDotenv>
|
|
|
49
48
|
processEnv: {},
|
|
50
49
|
});
|
|
51
50
|
|
|
52
|
-
if (
|
|
51
|
+
if (isError(envOutput.error))
|
|
53
52
|
throw envOutput.error;
|
|
54
53
|
return envOutput.parsed;
|
|
55
54
|
}
|
|
@@ -294,7 +293,7 @@ but the environment variable is empty or undefined.`);
|
|
|
294
293
|
* {@link NRI.PackPackagesOptionsType.t.propertyOverrides `propertyOverrides`}
|
|
295
294
|
* is a wrapper for MSBuild's `-property:<n>=<v>` properties override arg.
|
|
296
295
|
*/
|
|
297
|
-
static readonly PackPackagesOptionsType:
|
|
296
|
+
static readonly PackPackagesOptionsType: Type<{
|
|
298
297
|
propertyOverrides?: Record<string, string> | undefined;
|
|
299
298
|
artifactsPath?: string | undefined;
|
|
300
299
|
configuration?: 'Release' | 'Debug' | undefined;
|
|
@@ -345,7 +344,7 @@ but the environment variable is empty or undefined.`);
|
|
|
345
344
|
}),
|
|
346
345
|
);
|
|
347
346
|
|
|
348
|
-
public static readonly PackDummyPackagesOptionsType:
|
|
347
|
+
public static readonly PackDummyPackagesOptionsType: Type<{
|
|
349
348
|
propertyOverrides?: Record<string, string> | undefined;
|
|
350
349
|
artifactsPath?: string | undefined;
|
|
351
350
|
configuration?: 'Release' | 'Debug' | undefined;
|
|
@@ -559,7 +558,7 @@ but the environment variable is empty or undefined.`);
|
|
|
559
558
|
* Specific to this API:
|
|
560
559
|
* If you want to use this API's default root value (\`${cwd()}/publish`), assign an empty string.
|
|
561
560
|
*/
|
|
562
|
-
static readonly PushPackagesOptionsType:
|
|
561
|
+
static readonly PushPackagesOptionsType: Type<{
|
|
563
562
|
root: string;
|
|
564
563
|
apiKey?: string | undefined;
|
|
565
564
|
configFile?: string | undefined;
|
|
@@ -612,7 +611,7 @@ but the environment variable is empty or undefined.`);
|
|
|
612
611
|
* {@link NRI.PushPackagesOptionsType} sans {@link NRI.PushPackagesOptionsType.t.root}.
|
|
613
612
|
* The result of {@link getDummiesDir} is used, instead.
|
|
614
613
|
*/
|
|
615
|
-
public static readonly PushDummyPackagesOptionsType:
|
|
614
|
+
public static readonly PushDummyPackagesOptionsType: Type<{
|
|
616
615
|
apiKey?: string | undefined;
|
|
617
616
|
configFile?: string | undefined;
|
|
618
617
|
disableBuffering?: boolean | undefined;
|
|
@@ -730,7 +729,7 @@ but the environment variable is empty or undefined.`);
|
|
|
730
729
|
),
|
|
731
730
|
true,
|
|
732
731
|
).catch((error: unknown) => {
|
|
733
|
-
const _error: Error =
|
|
732
|
+
const _error: Error = isError(error) ? error : new Error(JSON.stringify(error));
|
|
734
733
|
throw opts.apiKey
|
|
735
734
|
? _censorTokenInError(_error, opts.apiKey)
|
|
736
735
|
: _error;
|
|
@@ -792,7 +791,7 @@ but the environment variable is empty or undefined.`);
|
|
|
792
791
|
const pushCmd: string = this.GetPushDummyCommand(opts);
|
|
793
792
|
return await execAsync(pushCmd, true)
|
|
794
793
|
.catch((error: unknown) => {
|
|
795
|
-
const _error: Error =
|
|
794
|
+
const _error: Error = isError(error) ? error : new Error(String(error));
|
|
796
795
|
throw opts.apiKey
|
|
797
796
|
? _censorTokenInError(_error, opts.apiKey)
|
|
798
797
|
: _error;
|
|
@@ -906,7 +905,7 @@ const NRI: typeof NugetRegistryInfo = NugetRegistryInfo;
|
|
|
906
905
|
* The base type for {@link NRIOpts} and related types. Extend this type while
|
|
907
906
|
* overriding member types via {@link NRIOptsBase.merge}
|
|
908
907
|
*/
|
|
909
|
-
export const NRIOptsBase:
|
|
908
|
+
export const NRIOptsBase: Type<{
|
|
910
909
|
project: MSBuildProject | {
|
|
911
910
|
readonly Items: Readonly<Required<MSBuildEvaluationOutput>['Items']>;
|
|
912
911
|
readonly Properties: Readonly<NugetProjectProperties>;
|
|
@@ -960,7 +959,7 @@ export const NRIOptsBase: ObjectType<{
|
|
|
960
959
|
/**
|
|
961
960
|
* The type of the parameter for {@link NugetRegistryInfo}'s constructor.
|
|
962
961
|
*/
|
|
963
|
-
export const NRIOpts:
|
|
962
|
+
export const NRIOpts: Type<{
|
|
964
963
|
project: MSBuildProject | {
|
|
965
964
|
readonly Items: Readonly<Required<MSBuildEvaluationOutput>['Items']>;
|
|
966
965
|
readonly Properties: Readonly<NugetProjectProperties>;
|
package/src/dotnet/helpers.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { type } from 'arktype';
|
|
1
|
+
import { type, type Type } from 'arktype';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { cwd } from 'node:process';
|
|
4
4
|
import { MSBuildProject } from './MSBuildProject.js';
|
|
5
5
|
import { MSBuildProjectProperties as MSBPP } from './MSBuildProjectProperties.js';
|
|
6
6
|
import { NugetRegistryInfo } from './NugetRegistryInfo.js';
|
|
7
7
|
import type { Default } from 'arktype/internal/attributes.ts';
|
|
8
|
-
import type { ObjectType } from 'arktype/internal/methods/object.ts';
|
|
9
8
|
|
|
10
9
|
const ourDefaultPubDir = path.join('.', 'publish') as `.${'/' | '\\'}publish`;
|
|
11
10
|
|
|
@@ -369,7 +368,7 @@ function formatDotnetNugetSign(
|
|
|
369
368
|
}
|
|
370
369
|
}
|
|
371
370
|
|
|
372
|
-
const DotnetNugetSignOptions:
|
|
371
|
+
const DotnetNugetSignOptions: Type<
|
|
373
372
|
{
|
|
374
373
|
timestamper: Default<string, 'https://rfc3161.ai.moda/'>;
|
|
375
374
|
certificatePassword?: string | undefined;
|
package/src/eslintConfig.ts
CHANGED
|
@@ -2,7 +2,7 @@ import eslint from '@eslint/js';
|
|
|
2
2
|
import { defineConfig, globalIgnores as setGlobalIgnores } from 'eslint/config';
|
|
3
3
|
import { type Linter } from 'eslint';
|
|
4
4
|
import stylistic, { type RuleOptions } from '@stylistic/eslint-plugin';
|
|
5
|
-
import
|
|
5
|
+
import json from '@eslint/json';
|
|
6
6
|
import globals from 'globals/globals.json' with { type: 'json' };
|
|
7
7
|
import tseslint from 'typescript-eslint';
|
|
8
8
|
|
|
@@ -24,59 +24,19 @@ const globalIgnores: ReturnType<typeof setGlobalIgnores> = setGlobalIgnores([
|
|
|
24
24
|
'**/*.tsbuildinfo',
|
|
25
25
|
'**/bin/**/*',
|
|
26
26
|
'**/obj/**/*',
|
|
27
|
+
'.pnp.cjs',
|
|
28
|
+
'.pnp.loader.mjs',
|
|
29
|
+
'.yarn/sdks/**',
|
|
27
30
|
]);
|
|
28
31
|
|
|
29
|
-
const json_json = {
|
|
30
|
-
/** jsonc config union types are a pain to work with. Each union member is mutually exclusive to the others */
|
|
31
|
-
...jsonc.configs['flat/recommended-with-json']
|
|
32
|
-
.map(v => v as JsoncCfgReducerIn)
|
|
33
|
-
.flatMap(a => jsonCfgReducer(a, {}))
|
|
34
|
-
// eslint-disable-next-line unicorn/no-array-reduce
|
|
35
|
-
.reduce((accumulator, element) => jsonCfgReducer(accumulator, element), {} as JsoncCfgReducerOut),
|
|
36
|
-
name: 'flat/recommended-with-json - https://github.com/ota-meshi/eslint-plugin-jsonc' as const,
|
|
37
|
-
files: ['*.json', '**/*.json'] as ['*.json', '**/*.json'],
|
|
38
|
-
ignores: globalIgnores.ignores,
|
|
39
|
-
};
|
|
40
|
-
const json_json5 = {
|
|
41
|
-
/** jsonc config union types are a pain to work with. Each union member is mutually exclusive to the others */
|
|
42
|
-
...jsonc.configs['flat/recommended-with-json5']
|
|
43
|
-
.map(v => v as JsoncCfgReducerIn)
|
|
44
|
-
.flatMap(a => jsonCfgReducer(a, {}))
|
|
45
|
-
// eslint-disable-next-line unicorn/no-array-reduce
|
|
46
|
-
.reduce((accumulator, element) => jsonCfgReducer(accumulator, element), {} as JsoncCfgReducerOut),
|
|
47
|
-
name: 'flat/recommended-with-json5 - https://github.com/ota-meshi/eslint-plugin-jsonc' as const,
|
|
48
|
-
files: ['*.json5', '**/*.json5'] as ['*.json5', '**/*.json5'],
|
|
49
|
-
ignores: globalIgnores.ignores,
|
|
50
|
-
};
|
|
51
|
-
const json_jsonc = {
|
|
52
|
-
/** jsonc config union types are a pain to work with. Each union member is mutually exclusive to the others */
|
|
53
|
-
...jsonc.configs['flat/recommended-with-jsonc']
|
|
54
|
-
.map(v => v as JsoncCfgReducerIn)
|
|
55
|
-
.flatMap(a => jsonCfgReducer(a, {}))
|
|
56
|
-
// eslint-disable-next-line unicorn/no-array-reduce
|
|
57
|
-
.reduce((accumulator, element) => jsonCfgReducer(accumulator, element), {} as JsoncCfgReducerOut),
|
|
58
|
-
name: 'flat/recommended-with-jsonc - https://github.com/ota-meshi/eslint-plugin-jsonc' as const,
|
|
59
|
-
files: ['*.jsonc', '**/*.jsonc'] as ['*.jsonc', '**/*.jsonc'],
|
|
60
|
-
ignores: globalIgnores.ignores,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
32
|
const stylisticWarn: Linter.Config = stylistic.configs.customize({
|
|
64
33
|
quoteProps: 'as-needed',
|
|
65
34
|
semi: true,
|
|
66
35
|
indent: 2,
|
|
36
|
+
severity: 'warn',
|
|
67
37
|
});
|
|
68
38
|
stylisticWarn.rules ??= {};
|
|
69
39
|
|
|
70
|
-
// change all stylistic error-severity to warn-severity. Style violations should not imply code errors.
|
|
71
|
-
for (const key in stylisticWarn.rules) {
|
|
72
|
-
const element = stylisticWarn.rules[key];
|
|
73
|
-
if (Array.isArray(element) && (element[0] === 2 || element[0] === 'error'))
|
|
74
|
-
element[0] = 'warn';
|
|
75
|
-
else if (element === 2 || element === 'error') {
|
|
76
|
-
stylisticWarn.rules[key] = 'warn';
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
40
|
stylisticWarn.rules['@stylistic/no-extra-parens'] = [
|
|
81
41
|
'warn',
|
|
82
42
|
'all',
|
|
@@ -96,9 +56,10 @@ stylisticWarn.rules['@stylistic/semi'] = [
|
|
|
96
56
|
] satisfies Linter.RuleEntry<RuleOptions['@stylistic/semi']>;
|
|
97
57
|
|
|
98
58
|
const config: ReturnType<typeof defineConfig> = defineConfig(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
59
|
+
{ ...json.configs.recommended, name: 'JSON Recommended', files: ['**/*.json'], language: 'json/json' },
|
|
60
|
+
{ name: 'JSON - Allow empty keys in package-lock.json', files: ['**/package-lock.json'], rules: { 'json/no-empty-keys': 'off' } },
|
|
61
|
+
{ ...json.configs.recommended, name: 'JSONC Recommended', files: ['**/*.jsonc'], language: 'json/jsonc' },
|
|
62
|
+
{ ...json.configs.recommended, name: 'JSON5 Recommended', files: ['**/*.json5'], language: 'json/json5' },
|
|
102
63
|
{
|
|
103
64
|
name: 'TSJS',
|
|
104
65
|
extends: [
|
|
@@ -128,56 +89,3 @@ const config: ReturnType<typeof defineConfig> = defineConfig(
|
|
|
128
89
|
globalIgnores,
|
|
129
90
|
);
|
|
130
91
|
export default config;
|
|
131
|
-
|
|
132
|
-
type JsoncCfgReducerIn = Partial<typeof jsonc.configs['flat/recommended-with-jsonc'][number]>
|
|
133
|
-
| Partial<typeof jsonc.configs['flat/recommended-with-json5'][number]>;
|
|
134
|
-
|
|
135
|
-
interface JsoncCfgReducerOut {
|
|
136
|
-
files: NonNullable<(typeof jsonc.configs)['flat/base'][number]['files']> | ['*.json', '**/*.json', '*.json5', '**/*.json5', '*.jsonc', '**/*.jsonc'];
|
|
137
|
-
plugins: typeof jsonc.configs['flat/base'][number]['plugins'];
|
|
138
|
-
languageOptions: {
|
|
139
|
-
parser: typeof import('jsonc-eslint-parser');
|
|
140
|
-
};
|
|
141
|
-
rules: NonNullable<
|
|
142
|
-
typeof jsonc['configs']['flat/recommended-with-json5'][number]['rules']
|
|
143
|
-
| typeof jsonc.configs['flat/recommended-with-jsonc'][number]['rules']
|
|
144
|
-
>;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Merge erroneously mutually-exclusive configs from `eslint-plugin-jsonc`.
|
|
149
|
-
* @param a A config exported by `eslint-plugin-jsonc` -OR- the output of this function.
|
|
150
|
-
* @param b A config exported by `eslint-plugin-jsonc` -OR- the output of this function.
|
|
151
|
-
* @returns A merged combination of {@link a} and {@link b}.
|
|
152
|
-
*/
|
|
153
|
-
function jsonCfgReducer(
|
|
154
|
-
a: JsoncCfgReducerIn | JsoncCfgReducerOut,
|
|
155
|
-
b: JsoncCfgReducerIn | JsoncCfgReducerOut,
|
|
156
|
-
): JsoncCfgReducerOut {
|
|
157
|
-
const baseRules = jsonc.configs['flat/base']
|
|
158
|
-
.find(
|
|
159
|
-
v => v.rules !== undefined,
|
|
160
|
-
)?.rules ?? (() => { throw new Error('Unable to find jsonc base rules'); })();
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
files: jsonc.configs['flat/base']
|
|
164
|
-
.filter(v => v.files !== undefined)
|
|
165
|
-
.flatMap(v => v.files),
|
|
166
|
-
plugins: {
|
|
167
|
-
jsonc: jsonc.configs['flat/base']
|
|
168
|
-
.find(v =>
|
|
169
|
-
v.plugins?.jsonc !== undefined,
|
|
170
|
-
)?.plugins?.jsonc ?? (() => { throw new Error('Unable to find jsonc plugin'); })(),
|
|
171
|
-
},
|
|
172
|
-
languageOptions: {
|
|
173
|
-
parser: jsonc.configs['flat/base']
|
|
174
|
-
.find(v => v.languageOptions?.parser)
|
|
175
|
-
?.languageOptions?.parser ?? (() => { throw new Error('Unable to find jsonc parser'); })(),
|
|
176
|
-
},
|
|
177
|
-
rules: {
|
|
178
|
-
...a.rules,
|
|
179
|
-
...b.rules,
|
|
180
|
-
...baseRules,
|
|
181
|
-
},
|
|
182
|
-
};
|
|
183
|
-
}
|
package/src/utils/execAsync.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/* eslint-disable jsdoc/no-defaults */
|
|
2
|
-
import { type } from 'arktype';
|
|
3
|
-
import type { ObjectType } from 'arktype/internal/methods/object.ts';
|
|
2
|
+
import { type, type Type } from 'arktype';
|
|
4
3
|
import { exec } from 'node:child_process';
|
|
5
4
|
import { constants } from 'node:os';
|
|
6
5
|
import { promisify } from 'node:util';
|
|
7
|
-
import {
|
|
6
|
+
import { isError } from './isError.js';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* A `promisify(exec)` wrapper to optionally assign the child process's STDERR as the {@link Error.prototype.cause}.
|
|
@@ -19,7 +18,7 @@ export async function execAsync(command: string, setStderrAsCause = false): Prom
|
|
|
19
18
|
stderr: string;
|
|
20
19
|
}> {
|
|
21
20
|
return await promisify(exec)(command).catch((error: unknown): never => {
|
|
22
|
-
if (!
|
|
21
|
+
if (!isError(error))
|
|
23
22
|
throw new Error(JSON.stringify(error));
|
|
24
23
|
|
|
25
24
|
if (setStderrAsCause && 'stderr' in error && typeof error.stderr === 'string' && error.stderr !== '')
|
|
@@ -40,7 +39,7 @@ export async function execAsync(command: string, setStderrAsCause = false): Prom
|
|
|
40
39
|
});
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
const T_ExecException:
|
|
42
|
+
const T_ExecException: Type<{
|
|
44
43
|
name: string;
|
|
45
44
|
message: string;
|
|
46
45
|
stack?: string | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isNativeError } from 'node:util/types';
|
|
2
|
+
|
|
3
|
+
/** @import 'typescript/lib/lib.esnext.error.d.ts' */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Compatibility wrapper for ES2026 (Node.js 25)
|
|
7
|
+
* {@link Error.isError Error.isError}
|
|
8
|
+
* with failover to the deprecated {@link isNativeError utils.types.isNativeError}.
|
|
9
|
+
* @param error A parameter which may be an Error.
|
|
10
|
+
* @returns `true` if {@link error} is derived from or is sufficiently similar to {@link Error}. Else, `false`.
|
|
11
|
+
* Note: DOMExceptions will result in `false`
|
|
12
|
+
*/
|
|
13
|
+
export function isError(error: unknown): error is Error {
|
|
14
|
+
return 'isError' in Error && typeof Error.isError === 'function' && Error.isError.length > 0
|
|
15
|
+
? (Error.isError as typeof isError)(error)
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
17
|
+
: isNativeError(error);
|
|
18
|
+
}
|
package/src/utils/miscTypes.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type, type Type } from 'arktype';
|
|
2
|
-
import type { StringType } from 'arktype/internal/methods/string.ts';
|
|
3
2
|
|
|
4
|
-
export const tBooleanString:
|
|
3
|
+
export const tBooleanString: Type<'false' | 'true'> = type('"true" | "false"');
|
|
5
4
|
export type BooleanString = typeof tBooleanString.infer;
|
|
6
5
|
|
|
7
6
|
export const tEmptyOrBooleanString: Type<'' | 'false' | 'true'> = type(tBooleanString.or('""'));
|