@typescript-calendar-lib/cli 0.2.5 → 0.2.7
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 +278 -0
- package/dist/bin.d.ts +28 -0
- package/dist/bin.js +164 -0
- package/dist/bin.js.map +1 -0
- package/dist/calendar-DNDADt5T.js +241 -0
- package/dist/calendar-DNDADt5T.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +2 -0
- package/dist/theme-BMYtCxK2.d.ts +53 -0
- package/package.json +15 -10
- package/src/align.ts +0 -35
- package/src/ansi.ts +0 -25
- package/src/bin.ts +0 -209
- package/src/border.ts +0 -55
- package/src/calendar.ts +0 -31
- package/src/index.ts +0 -24
- package/src/month.ts +0 -144
- package/src/render.ts +0 -5
- package/src/theme.ts +0 -146
- package/src/types.ts +0 -27
- package/src/year.ts +0 -48
package/README.md
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# @typescript-calendar-lib/cli
|
|
2
|
+
|
|
3
|
+
Render month, year, or date-range calendars as plain text — with optional ANSI colors, themes, and color schemes. Includes a command-line binary.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @typescript-calendar-lib/cli
|
|
9
|
+
# or
|
|
10
|
+
bun add @typescript-calendar-lib/cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Rendering API
|
|
14
|
+
|
|
15
|
+
### `calendar(options: CalendarOptions): string`
|
|
16
|
+
|
|
17
|
+
Render a single month:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { calendar } from "@typescript-calendar-lib/cli";
|
|
21
|
+
|
|
22
|
+
console.log(calendar({ year: 2026, month: 9 }));
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
September 2026
|
|
27
|
+
Sun Mon Tue Wed Thu Fri Sat
|
|
28
|
+
1 2 3 4 5
|
|
29
|
+
6 7 8 9 10 11 12
|
|
30
|
+
13 14 15 16 17 18 19
|
|
31
|
+
20 21 22 23 24 25 26
|
|
32
|
+
27 28 29 30
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### `calendarYear(options: CalendarYearOptions): string`
|
|
36
|
+
|
|
37
|
+
Render a full year as a 4 columns × 3 rows grid:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
console.log(calendarYear({ year: 2026 }));
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### `calendarRange(options: CalendarRangeOptions): string`
|
|
44
|
+
|
|
45
|
+
Render every month from `from` to `to` (inclusive), each on its own block:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
console.log(calendarRange({
|
|
49
|
+
from: new Date(2026, 5, 1),
|
|
50
|
+
to: new Date(2026, 8, 30),
|
|
51
|
+
}));
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Options
|
|
55
|
+
|
|
56
|
+
All options from `@typescript-calendar-lib/core` are supported, plus these CLI-specific extras:
|
|
57
|
+
|
|
58
|
+
| Option | Type | Default | Description |
|
|
59
|
+
| :--- | :--- | :--- | :--- |
|
|
60
|
+
| `theme` | `ThemeName \| CliTheme` | `"default"` | Visual theme (`"default"` \| `"modern"`) or custom theme object |
|
|
61
|
+
| `colorScheme` | `ColorSchemeName \| CliPalette` | `"default"` | Color scheme, active when `color: true` |
|
|
62
|
+
| `today` | `Date` | `new Date()` | Reference date for "today" coloring |
|
|
63
|
+
|
|
64
|
+
## CLI Binary
|
|
65
|
+
|
|
66
|
+
The package ships a `typescript-calendar-lib` binary:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
typescript-calendar-lib # current month
|
|
70
|
+
typescript-calendar-lib 2026 # current month of 2026
|
|
71
|
+
typescript-calendar-lib 2026 9 # September 2026
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Options
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
--theme <name> Look: default | modern (default: default)
|
|
78
|
+
--color-scheme <name> Colors: default | ocean | forest | sunset | mono
|
|
79
|
+
--color Enable ANSI colors
|
|
80
|
+
--locale <lang> Language: en | ja | es | de | fr | ko | zh (default: en)
|
|
81
|
+
--week-start <day> First weekday: sunday | monday (default: sunday)
|
|
82
|
+
--highlight <YYYY-MM-DD> Highlight a date (e.g. 2026-09-08)
|
|
83
|
+
--highlight-style <style> Highlight style: bracket | reverse (default: bracket)
|
|
84
|
+
-h, --help Show this help
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Example with `modern` theme and `ocean` color scheme:
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
typescript-calendar-lib 2026 9 --theme modern --color-scheme ocean --color
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Localized, Monday-start, with a highlighted date:
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
typescript-calendar-lib 2026 9 --locale ja --week-start monday --highlight 2026-09-08
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Themes
|
|
100
|
+
|
|
101
|
+
### `ThemeName`
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
type ThemeName = "default" | "modern";
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- **`"default"`** — plain text, space-separated cells, no frame
|
|
108
|
+
- **`"modern"`** — box-drawing frame (`┌───┬───┐` style)
|
|
109
|
+
|
|
110
|
+
### `CliTheme`
|
|
111
|
+
|
|
112
|
+
Custom themes are plain objects:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import type { CliTheme } from "@typescript-calendar-lib/cli";
|
|
116
|
+
|
|
117
|
+
const myTheme: CliTheme = {
|
|
118
|
+
cellWidth: 4,
|
|
119
|
+
separator: " | ",
|
|
120
|
+
frame: null, // or a FrameChars object for bordered layout
|
|
121
|
+
};
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
| Property | Type | Description |
|
|
125
|
+
| :--- | :--- | :--- |
|
|
126
|
+
| `cellWidth` | `number` | Width of each date cell |
|
|
127
|
+
| `separator` | `string` | Separator between cells |
|
|
128
|
+
| `frame` | `FrameChars \| null` | Frame characters, or `null` for no frame |
|
|
129
|
+
|
|
130
|
+
### `FrameChars`
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
interface FrameChars {
|
|
134
|
+
topLeft: string;
|
|
135
|
+
topRight: string;
|
|
136
|
+
bottomLeft: string;
|
|
137
|
+
bottomRight: string;
|
|
138
|
+
h: string; // horizontal line
|
|
139
|
+
v: string; // vertical line
|
|
140
|
+
j: string; // header/body intersection (┬, ┼)
|
|
141
|
+
footJ: string; // bottom intersection (┴)
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The built-in `"modern"` theme uses `┌ ┐ └ ┘ ─ │ ┬ ┴`.
|
|
146
|
+
|
|
147
|
+
### `THEMES`
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
const THEMES: Record<ThemeName, CliTheme>;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### `resolveTheme(theme?)`
|
|
154
|
+
|
|
155
|
+
Resolves a `ThemeName | CliTheme` to a `CliTheme` (defaults to `"default"`).
|
|
156
|
+
|
|
157
|
+
## Color Schemes
|
|
158
|
+
|
|
159
|
+
### `ColorSchemeName`
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
type ColorSchemeName = "default" | "ocean" | "forest" | "sunset" | "mono";
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
- **`"default"`** — colors range (yellow) and highlight (reverse) only
|
|
166
|
+
- **`"ocean"`** — cyan/blue palette
|
|
167
|
+
- **`"forest"`** — green palette
|
|
168
|
+
- **`"sunset"`** — magenta/orange palette
|
|
169
|
+
- **`"mono"`** — grayscale
|
|
170
|
+
|
|
171
|
+
### `CliPalette`
|
|
172
|
+
|
|
173
|
+
Each field is an ANSI foreground color code (or background code for highlight). `undefined` means "no coloring":
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
interface CliPalette {
|
|
177
|
+
title?: number;
|
|
178
|
+
weekday?: number;
|
|
179
|
+
day?: number;
|
|
180
|
+
weekend?: number;
|
|
181
|
+
today?: number;
|
|
182
|
+
highlight?: number; // used with highlightStyle: "reverse"
|
|
183
|
+
range?: number;
|
|
184
|
+
frame?: number;
|
|
185
|
+
dim?: number;
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
A custom palette can be passed directly:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
calendar({
|
|
193
|
+
year: 2026,
|
|
194
|
+
month: 9,
|
|
195
|
+
color: true,
|
|
196
|
+
colorScheme: { title: 36, range: 33, today: 33 },
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### `COLOR_SCHEMES` and `resolveColorScheme(scheme?)`
|
|
201
|
+
|
|
202
|
+
Predefined schemes and the resolver (defaults to `"default"`).
|
|
203
|
+
|
|
204
|
+
## Examples
|
|
205
|
+
|
|
206
|
+
### Highlight today
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
calendar({
|
|
210
|
+
year: 2026,
|
|
211
|
+
month: 9,
|
|
212
|
+
highlight: new Date(2026, 8, 8),
|
|
213
|
+
highlightStyle: "bracket", // [8]
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Reverse-video highlight requires `color: true`:
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
calendar({
|
|
221
|
+
year: 2026,
|
|
222
|
+
month: 9,
|
|
223
|
+
highlight: new Date(2026, 8, 8),
|
|
224
|
+
highlightStyle: "reverse",
|
|
225
|
+
color: true,
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Range coloring
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
calendar({
|
|
233
|
+
year: 2026,
|
|
234
|
+
month: 9,
|
|
235
|
+
range: { from: new Date(2026, 8, 1), to: new Date(2026, 8, 15) },
|
|
236
|
+
color: true,
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
When a date is both highlighted and in range, the highlight takes precedence.
|
|
241
|
+
|
|
242
|
+
### Plain text output
|
|
243
|
+
|
|
244
|
+
By default (`color: false`) the output contains no ANSI escape codes, so it's safe to pipe into files or other tools:
|
|
245
|
+
|
|
246
|
+
```sh
|
|
247
|
+
typescript-calendar-lib 2026 9 > september.txt
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Exports
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
import {
|
|
254
|
+
calendar,
|
|
255
|
+
calendarRange,
|
|
256
|
+
calendarYear,
|
|
257
|
+
COLOR_SCHEMES,
|
|
258
|
+
resolveColorScheme,
|
|
259
|
+
resolveTheme,
|
|
260
|
+
THEMES,
|
|
261
|
+
} from "@typescript-calendar-lib/cli";
|
|
262
|
+
|
|
263
|
+
import type {
|
|
264
|
+
CalendarOptions,
|
|
265
|
+
CalendarRangeOptions,
|
|
266
|
+
CalendarYearOptions,
|
|
267
|
+
CliPalette,
|
|
268
|
+
CliTheme,
|
|
269
|
+
ColorSchemeName,
|
|
270
|
+
FrameChars,
|
|
271
|
+
RenderMonthOptions,
|
|
272
|
+
ThemeName,
|
|
273
|
+
} from "@typescript-calendar-lib/cli";
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## License
|
|
277
|
+
|
|
278
|
+
MIT
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { i as ColorSchemeName, s as ThemeName } from "./theme-BMYtCxK2.js";
|
|
2
|
+
import { HighlightStyle, Locale, WeekStart } from "@typescript-calendar-lib/core";
|
|
3
|
+
//#region src/bin.d.ts
|
|
4
|
+
export interface CliArgs {
|
|
5
|
+
year?: number;
|
|
6
|
+
month?: number;
|
|
7
|
+
theme?: ThemeName;
|
|
8
|
+
colorScheme?: ColorSchemeName;
|
|
9
|
+
color?: boolean;
|
|
10
|
+
locale?: Locale;
|
|
11
|
+
weekStart?: WeekStart;
|
|
12
|
+
highlight?: Date;
|
|
13
|
+
highlightStyle?: HighlightStyle;
|
|
14
|
+
}
|
|
15
|
+
export interface ParseResult {
|
|
16
|
+
args: CliArgs;
|
|
17
|
+
error?: string;
|
|
18
|
+
help?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** YYYY-MM-DD 形式の日付文字列をパースする */
|
|
21
|
+
export declare function parseDate(value: string): Date | null;
|
|
22
|
+
/**
|
|
23
|
+
* CLI 引数をパースする。テスト可能なように副作用を分離している。
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseArgs(args: readonly string[]): ParseResult;
|
|
26
|
+
export declare function printUsage(): string;
|
|
27
|
+
//#endregion
|
|
28
|
+
//# sourceMappingURL=bin.d.ts.map
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { t as calendar } from "./calendar-DNDADt5T.js";
|
|
3
|
+
import { createDate } from "@typescript-calendar-lib/core";
|
|
4
|
+
//#region src/bin.ts
|
|
5
|
+
const THEMES = ["default", "modern"];
|
|
6
|
+
const COLOR_SCHEMES = [
|
|
7
|
+
"default",
|
|
8
|
+
"ocean",
|
|
9
|
+
"forest",
|
|
10
|
+
"sunset",
|
|
11
|
+
"mono"
|
|
12
|
+
];
|
|
13
|
+
const LOCALES = [
|
|
14
|
+
"en",
|
|
15
|
+
"ja",
|
|
16
|
+
"es",
|
|
17
|
+
"de",
|
|
18
|
+
"fr",
|
|
19
|
+
"ko",
|
|
20
|
+
"zh"
|
|
21
|
+
];
|
|
22
|
+
const WEEK_STARTS = ["sunday", "monday"];
|
|
23
|
+
const HIGHLIGHT_STYLES = ["bracket", "reverse"];
|
|
24
|
+
/** 値を一つ取るオプションと、代入先のフィールド名 */
|
|
25
|
+
const VALUE_OPTIONS = {
|
|
26
|
+
"--theme": "theme",
|
|
27
|
+
"--color-scheme": "colorScheme",
|
|
28
|
+
"--locale": "locale",
|
|
29
|
+
"--week-start": "weekStart",
|
|
30
|
+
"--highlight-style": "highlightStyle"
|
|
31
|
+
};
|
|
32
|
+
/** YYYY-MM-DD 形式の日付文字列をパースする */
|
|
33
|
+
function parseDate(value) {
|
|
34
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
35
|
+
if (!match) return null;
|
|
36
|
+
const year = Number(match[1]);
|
|
37
|
+
const month = Number(match[2]);
|
|
38
|
+
const day = Number(match[3]);
|
|
39
|
+
if (year < 1 || month < 1 || month > 12 || day < 1 || day > 31) return null;
|
|
40
|
+
const date = createDate(year, month - 1, day);
|
|
41
|
+
if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) return null;
|
|
42
|
+
return date;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* CLI 引数をパースする。テスト可能なように副作用を分離している。
|
|
46
|
+
*/
|
|
47
|
+
function parseArgs(args) {
|
|
48
|
+
const result = {};
|
|
49
|
+
const error = (message) => ({
|
|
50
|
+
args: result,
|
|
51
|
+
error: message
|
|
52
|
+
});
|
|
53
|
+
for (let i = 0; i < args.length; i++) {
|
|
54
|
+
const arg = args[i];
|
|
55
|
+
if (arg === "-h" || arg === "--help") return {
|
|
56
|
+
args: result,
|
|
57
|
+
help: true
|
|
58
|
+
};
|
|
59
|
+
if (arg === "--color") {
|
|
60
|
+
result.color = true;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (arg === "--highlight") {
|
|
64
|
+
const value = args[++i];
|
|
65
|
+
if (value === void 0) return error("Missing value for option: --highlight");
|
|
66
|
+
const parsed = parseDate(value);
|
|
67
|
+
if (parsed === null) return error(`Invalid --highlight date: "${value}" (expected YYYY-MM-DD, e.g. 2026-09-08)`);
|
|
68
|
+
result.highlight = parsed;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const key = VALUE_OPTIONS[arg];
|
|
72
|
+
if (key !== void 0) {
|
|
73
|
+
const value = args[++i];
|
|
74
|
+
if (value === void 0) return error(`Missing value for option: ${arg}`);
|
|
75
|
+
result[key] = value;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const numeric = /^-?\d+$/.test(arg);
|
|
79
|
+
if (arg.startsWith("-") && !numeric) return error(`Unknown option: ${arg}`);
|
|
80
|
+
if (!numeric) return error(`Invalid argument: "${arg}" (expected a year or month number)`);
|
|
81
|
+
if (result.year === void 0) result.year = Number(arg);
|
|
82
|
+
else if (result.month === void 0) result.month = Number(arg);
|
|
83
|
+
else return error(`Too many arguments: "${arg}"`);
|
|
84
|
+
}
|
|
85
|
+
if (result.year !== void 0 && (result.year < 1 || result.year > 9999)) return error(`Invalid year: ${result.year} (expected 1–9999)`);
|
|
86
|
+
if (result.month !== void 0 && (result.month < 1 || result.month > 12)) return error(`Invalid month: ${result.month} (expected 1–12)`);
|
|
87
|
+
const choiceTable = [
|
|
88
|
+
[
|
|
89
|
+
result.theme,
|
|
90
|
+
THEMES,
|
|
91
|
+
"theme"
|
|
92
|
+
],
|
|
93
|
+
[
|
|
94
|
+
result.colorScheme,
|
|
95
|
+
COLOR_SCHEMES,
|
|
96
|
+
"color-scheme"
|
|
97
|
+
],
|
|
98
|
+
[
|
|
99
|
+
result.locale,
|
|
100
|
+
LOCALES,
|
|
101
|
+
"locale"
|
|
102
|
+
],
|
|
103
|
+
[
|
|
104
|
+
result.weekStart,
|
|
105
|
+
WEEK_STARTS,
|
|
106
|
+
"week-start"
|
|
107
|
+
],
|
|
108
|
+
[
|
|
109
|
+
result.highlightStyle,
|
|
110
|
+
HIGHLIGHT_STYLES,
|
|
111
|
+
"highlight-style"
|
|
112
|
+
]
|
|
113
|
+
];
|
|
114
|
+
for (const [value, choices, name] of choiceTable) if (value !== void 0 && !choices.includes(value)) return error(`Invalid ${name}: "${value}" (expected: ${choices.join(" | ")})`);
|
|
115
|
+
return { args: result };
|
|
116
|
+
}
|
|
117
|
+
function printUsage() {
|
|
118
|
+
return `Usage: typescript-calendar-lib [YYYY] [MM] [options]
|
|
119
|
+
|
|
120
|
+
typescript-calendar-lib Render the current month
|
|
121
|
+
typescript-calendar-lib 2026 Render the current month of 2026
|
|
122
|
+
typescript-calendar-lib 2026 9 Render September 2026
|
|
123
|
+
|
|
124
|
+
Options:
|
|
125
|
+
--theme <name> Look: default | modern (default: default)
|
|
126
|
+
--color-scheme <name> Colors: default | ocean | forest | sunset | mono
|
|
127
|
+
--color Enable ANSI colors
|
|
128
|
+
--locale <lang> Language: en | ja | es | de | fr | ko | zh (default: en)
|
|
129
|
+
--week-start <day> First weekday: sunday | monday (default: sunday)
|
|
130
|
+
--highlight <YYYY-MM-DD> Highlight a date (e.g. 2026-09-08)
|
|
131
|
+
--highlight-style <style> Highlight style: bracket | reverse (default: bracket)
|
|
132
|
+
-h, --help Show this help
|
|
133
|
+
`;
|
|
134
|
+
}
|
|
135
|
+
if (import.meta.main) {
|
|
136
|
+
const { args, error, help } = parseArgs(process.argv.slice(2));
|
|
137
|
+
if (help) {
|
|
138
|
+
console.log(printUsage());
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
if (error) {
|
|
142
|
+
console.error(`Error: ${error}`);
|
|
143
|
+
console.error(printUsage());
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
const now = /* @__PURE__ */ new Date();
|
|
147
|
+
const year = args.year ?? now.getFullYear();
|
|
148
|
+
const month = args.month ?? now.getMonth() + 1;
|
|
149
|
+
console.log(calendar({
|
|
150
|
+
year,
|
|
151
|
+
month,
|
|
152
|
+
theme: args.theme,
|
|
153
|
+
colorScheme: args.colorScheme,
|
|
154
|
+
color: args.color,
|
|
155
|
+
locale: args.locale,
|
|
156
|
+
weekStart: args.weekStart,
|
|
157
|
+
highlight: args.highlight,
|
|
158
|
+
highlightStyle: args.highlightStyle
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
//#endregion
|
|
162
|
+
export { parseArgs, parseDate, printUsage };
|
|
163
|
+
|
|
164
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","names":[],"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env bun\nimport type {\n HighlightStyle,\n Locale,\n WeekStart,\n} from \"@typescript-calendar-lib/core\";\nimport { createDate } from \"@typescript-calendar-lib/core\";\nimport { calendar } from \"./calendar.ts\";\nimport type { ColorSchemeName, ThemeName } from \"./theme.ts\";\n\nexport interface CliArgs {\n year?: number;\n month?: number;\n theme?: ThemeName;\n colorScheme?: ColorSchemeName;\n color?: boolean;\n locale?: Locale;\n weekStart?: WeekStart;\n highlight?: Date;\n highlightStyle?: HighlightStyle;\n}\n\nexport interface ParseResult {\n args: CliArgs;\n error?: string;\n help?: boolean;\n}\n\nconst THEMES: readonly ThemeName[] = [\"default\", \"modern\"];\nconst COLOR_SCHEMES: readonly ColorSchemeName[] = [\n \"default\",\n \"ocean\",\n \"forest\",\n \"sunset\",\n \"mono\",\n];\nconst LOCALES: readonly Locale[] = [\"en\", \"ja\", \"es\", \"de\", \"fr\", \"ko\", \"zh\"];\nconst WEEK_STARTS: readonly WeekStart[] = [\"sunday\", \"monday\"];\nconst HIGHLIGHT_STYLES: readonly HighlightStyle[] = [\"bracket\", \"reverse\"];\n\n/** 値を一つ取るオプションと、代入先のフィールド名 */\nconst VALUE_OPTIONS: Record<string, keyof CliArgs> = {\n \"--theme\": \"theme\",\n \"--color-scheme\": \"colorScheme\",\n \"--locale\": \"locale\",\n \"--week-start\": \"weekStart\",\n \"--highlight-style\": \"highlightStyle\",\n};\n\n/** YYYY-MM-DD 形式の日付文字列をパースする */\nexport function parseDate(value: string): Date | null {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value);\n if (!match) return null;\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n if (year < 1 || month < 1 || month > 12 || day < 1 || day > 31) {\n return null;\n }\n const date = createDate(year, month - 1, day);\n if (\n date.getFullYear() !== year ||\n date.getMonth() !== month - 1 ||\n date.getDate() !== day\n ) {\n return null;\n }\n return date;\n}\n\n/**\n * CLI 引数をパースする。テスト可能なように副作用を分離している。\n */\nexport function parseArgs(args: readonly string[]): ParseResult {\n const result: CliArgs = {};\n const error = (message: string): ParseResult => ({\n args: result,\n error: message,\n });\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!;\n\n if (arg === \"-h\" || arg === \"--help\") {\n return { args: result, help: true };\n }\n if (arg === \"--color\") {\n result.color = true;\n continue;\n }\n if (arg === \"--highlight\") {\n const value = args[++i];\n if (value === undefined) {\n return error(\"Missing value for option: --highlight\");\n }\n const parsed = parseDate(value);\n if (parsed === null) {\n return error(\n `Invalid --highlight date: \"${value}\" (expected YYYY-MM-DD, e.g. 2026-09-08)`,\n );\n }\n result.highlight = parsed;\n continue;\n }\n\n const key = VALUE_OPTIONS[arg];\n if (key !== undefined) {\n const value = args[++i];\n if (value === undefined) {\n return error(`Missing value for option: ${arg}`);\n }\n (result as Record<string, unknown>)[key] = value;\n continue;\n }\n\n const numeric = /^-?\\d+$/.test(arg);\n if (arg.startsWith(\"-\") && !numeric) {\n return error(`Unknown option: ${arg}`);\n }\n if (!numeric) {\n return error(\n `Invalid argument: \"${arg}\" (expected a year or month number)`,\n );\n }\n if (result.year === undefined) {\n result.year = Number(arg);\n } else if (result.month === undefined) {\n result.month = Number(arg);\n } else {\n return error(`Too many arguments: \"${arg}\"`);\n }\n }\n\n // 値のバリデーション\n if (result.year !== undefined && (result.year < 1 || result.year > 9999)) {\n return error(`Invalid year: ${result.year} (expected 1–9999)`);\n }\n if (result.month !== undefined && (result.month < 1 || result.month > 12)) {\n return error(`Invalid month: ${result.month} (expected 1–12)`);\n }\n\n const choiceTable: Array<[string | undefined, readonly string[], string]> = [\n [result.theme, THEMES, \"theme\"],\n [result.colorScheme, COLOR_SCHEMES, \"color-scheme\"],\n [result.locale, LOCALES, \"locale\"],\n [result.weekStart, WEEK_STARTS, \"week-start\"],\n [result.highlightStyle, HIGHLIGHT_STYLES, \"highlight-style\"],\n ];\n for (const [value, choices, name] of choiceTable) {\n if (value !== undefined && !choices.includes(value)) {\n return error(\n `Invalid ${name}: \"${value}\" (expected: ${choices.join(\" | \")})`,\n );\n }\n }\n\n return { args: result };\n}\n\nexport function printUsage(): string {\n return `Usage: typescript-calendar-lib [YYYY] [MM] [options]\n\n typescript-calendar-lib Render the current month\n typescript-calendar-lib 2026 Render the current month of 2026\n typescript-calendar-lib 2026 9 Render September 2026\n\nOptions:\n --theme <name> Look: default | modern (default: default)\n --color-scheme <name> Colors: default | ocean | forest | sunset | mono\n --color Enable ANSI colors\n --locale <lang> Language: en | ja | es | de | fr | ko | zh (default: en)\n --week-start <day> First weekday: sunday | monday (default: sunday)\n --highlight <YYYY-MM-DD> Highlight a date (e.g. 2026-09-08)\n --highlight-style <style> Highlight style: bracket | reverse (default: bracket)\n -h, --help Show this help\n`;\n}\n\nif (import.meta.main) {\n const { args, error, help } = parseArgs(process.argv.slice(2));\n\n if (help) {\n console.log(printUsage());\n process.exit(0);\n }\n if (error) {\n console.error(`Error: ${error}`);\n console.error(printUsage());\n process.exit(1);\n }\n\n const now = new Date();\n const year = args.year ?? now.getFullYear();\n const month = args.month ?? now.getMonth() + 1;\n\n console.log(\n calendar({\n year,\n month,\n theme: args.theme,\n colorScheme: args.colorScheme,\n color: args.color,\n locale: args.locale,\n weekStart: args.weekStart,\n highlight: args.highlight,\n highlightStyle: args.highlightStyle,\n }),\n );\n}\n"],"mappings":"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"}
|