Skip to content

Commit bac8c2e

Browse files
committed
feat: number input
1 parent 389c475 commit bac8c2e

File tree

17 files changed

+973
-56
lines changed

17 files changed

+973
-56
lines changed

src/compose/get-options-variables.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { InputChoiceStateInitial } from '../input/choice/types'
44
import type { InputCountStateInitial } from '../input/count/types'
55
import type { InputGroupStateInitial } from '../input/group/types'
66
import type { InputStringStateInitial } from '../input/string/types'
7+
import type { InputNumberStateInitial } from '../input/number/types'
78
import { type GenericOption, type GenericVariable, InputType, type Match } from '../types'
89

910
export const getOptionsVariables = (
@@ -12,6 +13,7 @@ export const getOptionsVariables = (
1213
| InputChoiceStateInitial
1314
| InputCountStateInitial
1415
| InputGroupStateInitial
16+
| InputNumberStateInitial
1517
| InputStringStateInitial,
1618
match: Match,
1719
) => {

src/compose/get-specification.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { SYMBOL_LOG, SYMBOL_STATE } from '@escapace/fluent'
22
import arg from 'arg'
33
import { assign, filter, flatMap, map } from 'lodash-es'
4-
import { type CommandActionInput, type Command, CommandTypeAction } from '../command/types'
4+
import { type Command, type CommandActionInput, CommandTypeAction } from '../command/types'
55
import type { InputGroup } from '../input/group/types'
66
import {
77
type Input,
@@ -11,6 +11,7 @@ import {
1111
SYMBOL_INPUT_CHOICE,
1212
SYMBOL_INPUT_COUNT,
1313
SYMBOL_INPUT_GROUP,
14+
SYMBOL_INPUT_NUMBER,
1415
SYMBOL_INPUT_STRING,
1516
} from '../types'
1617

@@ -26,6 +27,8 @@ const match = (
2627
return state.repeat ? [String] : String
2728
case SYMBOL_INPUT_COUNT:
2829
return arg.COUNT
30+
case SYMBOL_INPUT_NUMBER:
31+
return state.repeat ? [Number] : Number
2932
case SYMBOL_INPUT_STRING:
3033
return state.repeat ? [String] : String
3134
}

src/example.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { choice } from './input/choice/domain-language'
55
import { count } from './input/count/domain-language'
66
import { group } from './input/group/domain-language'
77
import { string } from './input/string/domain-language'
8+
import { number } from './input/number/domain-language'
89

910
export const grant = string()
1011
.reference('GRANT')
@@ -28,7 +29,7 @@ export const retrace = count()
2829
.option('-r', '-d')
2930
.default(2)
3031

31-
export const pummel = string()
32+
export const pummel = number()
3233
.reference('PUMMEL')
3334
.description(
3435
'Furlong furlong focal for the genuflect profound of the motif aloof and offers. Gnome gnome gondola for the impugn logos',
@@ -37,7 +38,7 @@ export const pummel = string()
3738
.option('--pummel')
3839
.option('-p')
3940
.variable('PUMMEL')
40-
.default(['bison', 'tunnel'])
41+
.default([1024, 512])
4142

4243
export const wick = choice()
4344
.reference('WICK')

src/help/inputs/input-number.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* eslint-disable typescript/no-non-null-assertion */
2+
import { SYMBOL_STATE } from '@escapace/fluent'
3+
import type { InputNumber } from '../../input/number/types'
4+
import type { PropertiesShared, SYMBOL_INPUT_NUMBER } from '../../types'
5+
import { HELP_SIGN_REPEAT } from '../constants'
6+
import { enclose } from '../enclose'
7+
import type { HelpInputsExcluding } from '../types'
8+
9+
export const usageInputNumber = (
10+
input: InputNumber,
11+
depth: number,
12+
properties: PropertiesShared,
13+
): HelpInputsExcluding<typeof SYMBOL_INPUT_NUMBER> => {
14+
const { description, options, repeat, type, variables } = input[SYMBOL_STATE]
15+
16+
return {
17+
depth,
18+
description: description!,
19+
options:
20+
options.length === 0
21+
? undefined
22+
: `[${enclose(options)}=<number>]${repeat ? `${HELP_SIGN_REPEAT}` : ''}`,
23+
type: type as typeof SYMBOL_INPUT_NUMBER,
24+
variables:
25+
variables.length === 0
26+
? undefined
27+
: `${enclose(variables)}=${
28+
repeat
29+
? `<number>[${properties.settings.separator}<number>]${HELP_SIGN_REPEAT}`
30+
: '<number>'
31+
}`,
32+
}
33+
}

src/help/inputs/input.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@ import type { InputBoolean } from '../../input/boolean/types'
33
import type { InputChoice } from '../../input/choice/types'
44
import type { InputCount } from '../../input/count/types'
55
import type { InputGroup } from '../../input/group/types'
6+
import type { InputNumber } from '../../input/number/types'
67
import type { InputString } from '../../input/string/types'
78
import {
89
type Input,
910
type PropertiesShared,
1011
SYMBOL_INPUT_BOOLEAN,
1112
SYMBOL_INPUT_CHOICE,
1213
SYMBOL_INPUT_COUNT,
14+
SYMBOL_INPUT_NUMBER,
1315
SYMBOL_INPUT_STRING,
1416
} from '../../types'
1517
import type { HelpInputsExcluding } from '../types'
1618
import { usageInputBoolean } from './input-boolean'
1719
import { usageInputChoice } from './input-choice'
1820
import { usageInputCount } from './input-count'
21+
import { usageInputNumber } from './input-number'
1922
import { usageInputString } from './input-string'
2023

2124
export const usageInput = (
@@ -30,6 +33,8 @@ export const usageInput = (
3033
return usageInputChoice(input as InputChoice, depth, properties)
3134
case SYMBOL_INPUT_COUNT:
3235
return usageInputCount(input as InputCount, depth)
36+
case SYMBOL_INPUT_NUMBER:
37+
return usageInputNumber(input as InputNumber, depth, properties)
3338
case SYMBOL_INPUT_STRING:
3439
return usageInputString(input as InputString, depth, properties)
3540
}

src/input/boolean/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ import type {
1212
} from '@escapace/fluent'
1313

1414
import type {
15-
InputType,
1615
InputPropertiesShared,
16+
InputType,
1717
Reference,
18-
StateSharedInitial,
1918
StateShared,
19+
StateSharedInitial,
2020
SYMBOL_INPUT_BOOLEAN,
2121
} from '../../types'
2222

@@ -292,7 +292,7 @@ interface ModelInputBoolean {
292292
readonly state: InputBoolean[typeof SYMBOL_STATE]
293293
}
294294

295-
export interface InputBooleanProperties extends InputPropertiesShared {
295+
interface InputBooleanProperties extends InputPropertiesShared {
296296
readonly model: ModelInputBoolean
297297
}
298298

src/input/count/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import type {
1313
GenericOption,
1414
InputPropertiesShared,
1515
Reference,
16-
StateSharedInitial,
1716
StateShared,
17+
StateSharedInitial,
1818
SYMBOL_INPUT_COUNT,
1919
} from '../../types'
2020

@@ -213,7 +213,7 @@ interface InputCountModel {
213213
readonly state: InputCount[typeof SYMBOL_STATE]
214214
}
215215

216-
export interface InputCountProperties extends InputPropertiesShared {
216+
interface InputCountProperties extends InputPropertiesShared {
217217
readonly model: InputCountModel
218218
}
219219

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import { log, state, SYMBOL_LOG, SYMBOL_STATE } from '@escapace/fluent'
2+
import { assert, describe, it } from 'vitest'
3+
import { SYMBOL_INPUT_NUMBER } from '../../types'
4+
import { number } from './domain-language'
5+
import { reducer } from './reducer'
6+
import { InputNumberTypeAction } from './types'
7+
8+
describe('input/number', () => {
9+
it('domain-language', () => {
10+
const reference = 'test'
11+
12+
assert.isFunction(number)
13+
14+
const test0 = number()
15+
16+
assert.hasAllKeys(test0, [SYMBOL_LOG, SYMBOL_STATE, 'reference'])
17+
18+
assert.deepEqual(log(test0), [])
19+
20+
assert.deepEqual(state(test0), {
21+
default: undefined,
22+
description: undefined,
23+
isEmpty: true,
24+
options: [],
25+
reducer,
26+
reference: undefined,
27+
repeat: false,
28+
type: SYMBOL_INPUT_NUMBER,
29+
variables: [],
30+
})
31+
32+
const test1 = test0.reference(reference)
33+
34+
assert.hasAllKeys(test1, [SYMBOL_LOG, SYMBOL_STATE, 'description'])
35+
36+
assert.deepEqual(log(test1), [{ payload: reference, type: InputNumberTypeAction.Reference }])
37+
38+
assert.deepEqual(state(test1), {
39+
default: undefined,
40+
description: undefined,
41+
isEmpty: true,
42+
options: [],
43+
reducer,
44+
reference,
45+
repeat: false,
46+
type: SYMBOL_INPUT_NUMBER,
47+
variables: [],
48+
})
49+
50+
const test2 = test1.description('ABC')
51+
52+
assert.hasAllKeys(test2, [SYMBOL_LOG, SYMBOL_STATE, 'repeat', 'option', 'variable'])
53+
54+
assert.deepEqual(log(test2), [
55+
{ payload: 'ABC', type: InputNumberTypeAction.Description },
56+
{ payload: reference, type: InputNumberTypeAction.Reference },
57+
])
58+
59+
assert.deepEqual(state(test2), {
60+
default: undefined,
61+
description: 'ABC',
62+
isEmpty: true,
63+
options: [],
64+
reducer,
65+
reference,
66+
repeat: false,
67+
type: SYMBOL_INPUT_NUMBER,
68+
variables: [],
69+
})
70+
71+
const test3 = test2.repeat()
72+
73+
assert.hasAllKeys(test3, [SYMBOL_LOG, SYMBOL_STATE, 'option', 'variable'])
74+
75+
assert.deepEqual(log(test3), [
76+
{ payload: undefined, type: InputNumberTypeAction.Repeat },
77+
{ payload: 'ABC', type: InputNumberTypeAction.Description },
78+
{ payload: reference, type: InputNumberTypeAction.Reference },
79+
])
80+
81+
assert.deepEqual(state(test3), {
82+
default: undefined,
83+
description: 'ABC',
84+
isEmpty: true,
85+
options: [],
86+
reducer,
87+
reference,
88+
repeat: true,
89+
type: SYMBOL_INPUT_NUMBER,
90+
variables: [],
91+
})
92+
93+
const test4 = test3.option('--option')
94+
95+
assert.hasAllKeys(test4, [SYMBOL_LOG, SYMBOL_STATE, 'default', 'option', 'variable'])
96+
97+
assert.deepEqual(log(test4), [
98+
{
99+
payload: {
100+
name: '--option',
101+
},
102+
type: InputNumberTypeAction.Option,
103+
},
104+
{ payload: undefined, type: InputNumberTypeAction.Repeat },
105+
{ payload: 'ABC', type: InputNumberTypeAction.Description },
106+
{ payload: reference, type: InputNumberTypeAction.Reference },
107+
])
108+
109+
assert.deepEqual(state(test4), {
110+
default: undefined,
111+
description: 'ABC',
112+
isEmpty: false,
113+
options: ['--option'],
114+
reducer,
115+
reference,
116+
repeat: true,
117+
type: SYMBOL_INPUT_NUMBER,
118+
variables: [],
119+
})
120+
121+
const test5 = test4.variable('VARIABLE')
122+
123+
assert.hasAllKeys(test5, [SYMBOL_LOG, SYMBOL_STATE, 'default', 'option', 'variable'])
124+
125+
assert.deepEqual(log(test5), [
126+
{
127+
payload: 'VARIABLE',
128+
type: InputNumberTypeAction.Variable,
129+
},
130+
{
131+
payload: {
132+
name: '--option',
133+
},
134+
type: InputNumberTypeAction.Option,
135+
},
136+
{ payload: undefined, type: InputNumberTypeAction.Repeat },
137+
{ payload: 'ABC', type: InputNumberTypeAction.Description },
138+
{ payload: reference, type: InputNumberTypeAction.Reference },
139+
])
140+
141+
assert.deepEqual(state(test5), {
142+
default: undefined,
143+
description: 'ABC',
144+
isEmpty: false,
145+
options: ['--option'],
146+
reducer,
147+
reference,
148+
repeat: true,
149+
type: SYMBOL_INPUT_NUMBER,
150+
variables: ['VARIABLE'],
151+
})
152+
153+
const test6 = test5.default([1, 2, 3])
154+
155+
assert.hasAllKeys(test6, [SYMBOL_LOG, SYMBOL_STATE])
156+
157+
assert.deepEqual(log(test6), [
158+
{ payload: [1, 2, 3], type: InputNumberTypeAction.Default },
159+
{
160+
payload: 'VARIABLE',
161+
type: InputNumberTypeAction.Variable,
162+
},
163+
{
164+
payload: {
165+
name: '--option',
166+
},
167+
type: InputNumberTypeAction.Option,
168+
},
169+
{ payload: undefined, type: InputNumberTypeAction.Repeat },
170+
{ payload: 'ABC', type: InputNumberTypeAction.Description },
171+
{ payload: reference, type: InputNumberTypeAction.Reference },
172+
])
173+
174+
assert.deepEqual(state(test6), {
175+
default: [1, 2, 3],
176+
description: 'ABC',
177+
isEmpty: false,
178+
options: ['--option'],
179+
reducer,
180+
reference,
181+
repeat: true,
182+
type: SYMBOL_INPUT_NUMBER,
183+
variables: ['VARIABLE'],
184+
})
185+
})
186+
})

0 commit comments

Comments
 (0)