@poetora/cli 0.0.1 → 0.1.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/.turbo/turbo-build.log +4 -0
- package/LICENSE +93 -0
- package/bin/accessibility.js +2 -2
- package/bin/cli-builder.d.ts +8 -0
- package/bin/cli-builder.js +178 -0
- package/bin/cli.d.ts +5 -11
- package/bin/cli.js +8 -200
- package/bin/commands/base.command.d.ts +13 -0
- package/bin/commands/base.command.js +40 -0
- package/bin/commands/check.command.d.ts +14 -0
- package/bin/commands/check.command.js +21 -0
- package/bin/commands/dev.command.d.ts +13 -0
- package/bin/commands/dev.command.js +40 -0
- package/bin/commands/index.d.ts +6 -0
- package/bin/commands/index.js +6 -0
- package/bin/commands/init.command.d.ts +16 -0
- package/bin/commands/init.command.js +88 -0
- package/bin/commands/link.command.d.ts +13 -0
- package/bin/commands/link.command.js +19 -0
- package/bin/commands/update.command.d.ts +10 -0
- package/bin/commands/update.command.js +13 -0
- package/bin/constants.js +1 -1
- package/bin/errors/cli-error.d.ts +26 -0
- package/bin/errors/cli-error.js +53 -0
- package/bin/errors/index.d.ts +1 -0
- package/bin/errors/index.js +1 -0
- package/bin/index.d.ts +1 -1
- package/bin/index.js +6 -6
- package/bin/mdxAccessibility.js +2 -2
- package/bin/services/accessibility-check.service.d.ts +10 -0
- package/bin/services/accessibility-check.service.js +144 -0
- package/bin/services/index.d.ts +7 -0
- package/bin/services/index.js +7 -0
- package/bin/services/link.service.d.ts +7 -0
- package/bin/services/link.service.js +40 -0
- package/bin/services/openapi-check.service.d.ts +7 -0
- package/bin/services/openapi-check.service.js +43 -0
- package/bin/services/port.service.d.ts +7 -0
- package/bin/services/port.service.js +26 -0
- package/bin/services/template.service.d.ts +22 -0
- package/bin/services/template.service.js +127 -0
- package/bin/services/update.service.d.ts +10 -0
- package/bin/services/update.service.js +57 -0
- package/bin/services/version.service.d.ts +16 -0
- package/bin/services/version.service.js +102 -0
- package/bin/types/common.d.ts +38 -0
- package/bin/types/common.js +21 -0
- package/bin/types/index.d.ts +2 -0
- package/bin/types/index.js +2 -0
- package/bin/types/options.d.ts +23 -0
- package/bin/types/options.js +1 -0
- package/bin/utils/console-logger.d.ts +16 -0
- package/bin/utils/console-logger.js +65 -0
- package/bin/utils/index.d.ts +2 -0
- package/bin/utils/index.js +2 -0
- package/bin/utils/logger.interface.d.ts +15 -0
- package/bin/utils/logger.interface.js +1 -0
- package/package.json +29 -29
- package/src/accessibility.ts +2 -2
- package/src/cli-builder.ts +267 -0
- package/src/cli.ts +15 -0
- package/src/commands/__tests__/base.command.test.ts +145 -0
- package/src/commands/__tests__/dev.command.test.ts +241 -0
- package/src/commands/__tests__/init.command.test.ts +281 -0
- package/{__test__ → src/commands/__tests__}/utils.ts +1 -1
- package/src/commands/base.command.ts +97 -0
- package/src/commands/check.command.ts +40 -0
- package/src/commands/dev.command.ts +63 -0
- package/src/commands/index.ts +6 -0
- package/src/commands/init.command.ts +125 -0
- package/src/commands/link.command.ts +39 -0
- package/src/commands/update.command.ts +23 -0
- package/src/constants.ts +1 -1
- package/src/errors/cli-error.ts +83 -0
- package/src/errors/index.ts +1 -0
- package/src/index.ts +6 -6
- package/src/mdxAccessibility.ts +3 -4
- package/src/services/__tests__/port.service.test.ts +83 -0
- package/src/services/__tests__/template.service.test.ts +234 -0
- package/src/services/__tests__/version.service.test.ts +165 -0
- package/src/services/accessibility-check.service.ts +226 -0
- package/src/services/index.ts +7 -0
- package/src/services/link.service.ts +65 -0
- package/src/services/openapi-check.service.ts +68 -0
- package/src/services/port.service.ts +47 -0
- package/src/services/template.service.ts +203 -0
- package/src/services/update.service.ts +76 -0
- package/src/services/version.service.ts +161 -0
- package/src/types/common.ts +53 -0
- package/src/types/index.ts +2 -0
- package/src/types/options.ts +42 -0
- package/src/utils/console-logger.ts +114 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/logger.interface.ts +70 -0
- package/tsconfig.build.json +2 -1
- package/tsconfig.json +1 -1
- package/.prettierignore +0 -2
- package/__test__/brokenLinks.test.ts +0 -93
- package/__test__/checkPort.test.ts +0 -92
- package/__test__/openApiCheck.test.ts +0 -127
- package/__test__/update.test.ts +0 -108
- package/bin/accessibilityCheck.d.ts +0 -2
- package/bin/accessibilityCheck.js +0 -70
- package/bin/helpers.d.ts +0 -17
- package/bin/helpers.js +0 -104
- package/bin/init.d.ts +0 -1
- package/bin/init.js +0 -73
- package/bin/mdxLinter.d.ts +0 -2
- package/bin/mdxLinter.js +0 -45
- package/bin/update.d.ts +0 -3
- package/bin/update.js +0 -32
- package/src/accessibilityCheck.tsx +0 -145
- package/src/cli.tsx +0 -302
- package/src/helpers.tsx +0 -131
- package/src/init.tsx +0 -93
- package/src/mdxLinter.tsx +0 -88
- package/src/update.tsx +0 -37
package/LICENSE
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright (c) 2025 Poetora
|
|
2
|
+
|
|
3
|
+
Elastic License 2.0
|
|
4
|
+
|
|
5
|
+
## Acceptance
|
|
6
|
+
|
|
7
|
+
By using the software, you agree to all of the terms and conditions below.
|
|
8
|
+
|
|
9
|
+
## Copyright License
|
|
10
|
+
|
|
11
|
+
The licensor grants you a non-exclusive, royalty-free, worldwide,
|
|
12
|
+
non-sublicensable, non-transferable license to use, copy, distribute, make
|
|
13
|
+
available, and prepare derivative works of the software, in each case subject to
|
|
14
|
+
the limitations and conditions below.
|
|
15
|
+
|
|
16
|
+
## Limitations
|
|
17
|
+
|
|
18
|
+
You may not provide the software to third parties as a hosted or managed
|
|
19
|
+
service, where the service provides users with access to any substantial set of
|
|
20
|
+
the features or functionality of the software.
|
|
21
|
+
|
|
22
|
+
You may not move, change, disable, or circumvent the license key functionality
|
|
23
|
+
in the software, and you may not remove or obscure any functionality in the
|
|
24
|
+
software that is protected by the license key.
|
|
25
|
+
|
|
26
|
+
You may not alter, remove, or obscure any licensing, copyright, or other notices
|
|
27
|
+
of the licensor in the software. Any use of the licensor’s trademarks is subject
|
|
28
|
+
to applicable law.
|
|
29
|
+
|
|
30
|
+
## Patents
|
|
31
|
+
|
|
32
|
+
The licensor grants you a license, under any patent claims the licensor can
|
|
33
|
+
license, or becomes able to license, to make, have made, use, sell, offer for
|
|
34
|
+
sale, import and have imported the software, in each case subject to the
|
|
35
|
+
limitations and conditions in this license. This license does not cover any
|
|
36
|
+
patent claims that you cause to be infringed by modifications or additions to
|
|
37
|
+
the software. If you or your company make any written claim that the software
|
|
38
|
+
infringes or contributes to infringement of any patent, your patent license for
|
|
39
|
+
the software granted under these terms ends immediately. If your company makes
|
|
40
|
+
such a claim, your patent license ends immediately for work on behalf of your
|
|
41
|
+
company.
|
|
42
|
+
|
|
43
|
+
## Notices
|
|
44
|
+
|
|
45
|
+
You must ensure that anyone who gets a copy of any part of the software from you
|
|
46
|
+
also gets a copy of these terms.
|
|
47
|
+
|
|
48
|
+
If you modify the software, you must include in any modified copies of the
|
|
49
|
+
software prominent notices stating that you have modified the software.
|
|
50
|
+
|
|
51
|
+
## No Other Rights
|
|
52
|
+
|
|
53
|
+
These terms do not imply any licenses other than those expressly granted in
|
|
54
|
+
these terms.
|
|
55
|
+
|
|
56
|
+
## Termination
|
|
57
|
+
|
|
58
|
+
If you use the software in violation of these terms, such use is not licensed,
|
|
59
|
+
and your licenses will automatically terminate. If the licensor provides you
|
|
60
|
+
with a notice of your violation, and you cease all violation of this license no
|
|
61
|
+
later than 30 days after you receive that notice, your licenses will be
|
|
62
|
+
reinstated retroactively. However, if you violate these terms after such
|
|
63
|
+
reinstatement, any additional violation of these terms will cause your licenses
|
|
64
|
+
to terminate automatically and permanently.
|
|
65
|
+
|
|
66
|
+
## No Liability
|
|
67
|
+
|
|
68
|
+
_As far as the law allows, the software comes as is, without any warranty or
|
|
69
|
+
condition, and the licensor will not be liable to you for any damages arising
|
|
70
|
+
out of these terms or the use or nature of the software, under any kind of
|
|
71
|
+
legal claim._
|
|
72
|
+
|
|
73
|
+
## Definitions
|
|
74
|
+
|
|
75
|
+
The **licensor** is the entity offering these terms, and the **software** is the
|
|
76
|
+
software the licensor makes available under these terms, including any portion
|
|
77
|
+
of it.
|
|
78
|
+
|
|
79
|
+
**you** refers to the individual or entity agreeing to these terms.
|
|
80
|
+
|
|
81
|
+
**your company** is any legal entity, sole proprietorship, or other kind of
|
|
82
|
+
organization that you work for, plus all organizations that have control over,
|
|
83
|
+
are under the control of, or are under common control with that
|
|
84
|
+
organization. **control** means ownership of substantially all the assets of an
|
|
85
|
+
entity, or the power to direct its management and policies by vote, contract, or
|
|
86
|
+
otherwise. Control can be direct or indirect.
|
|
87
|
+
|
|
88
|
+
**your licenses** are all the licenses granted to you for the software under
|
|
89
|
+
these terms.
|
|
90
|
+
|
|
91
|
+
**use** means anything you do with the software requiring one of your licenses.
|
|
92
|
+
|
|
93
|
+
**trademark** means trademarks, service marks, and similar rights.
|
package/bin/accessibility.js
CHANGED
|
@@ -87,8 +87,8 @@ export function checkDocsColors(colors, background, navigation) {
|
|
|
87
87
|
darkOnLightContrast,
|
|
88
88
|
...anchorResults.flatMap((anchor) => [anchor.lightContrast, anchor.darkContrast]),
|
|
89
89
|
].filter(Boolean);
|
|
90
|
-
const hasFailure = results.some((result) => result
|
|
91
|
-
const hasWarning = results.some((result) => result
|
|
90
|
+
const hasFailure = results.some((result) => result?.recommendation === 'fail');
|
|
91
|
+
const hasWarning = results.some((result) => result?.recommendation === 'warning');
|
|
92
92
|
let overallScore;
|
|
93
93
|
if (hasFailure) {
|
|
94
94
|
overallScore = 'fail';
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import yargs from 'yargs';
|
|
2
|
+
import { hideBin } from 'yargs/helpers';
|
|
3
|
+
import { CheckCommand, DevCommand, InitCommand, LinkCommand, UpdateCommand, } from './commands/index.js';
|
|
4
|
+
import { AccessibilityCheckService, LinkService, OpenApiCheckService, PortService, TemplateService, UpdateService, VersionService, } from './services/index.js';
|
|
5
|
+
import { ConsoleLogger } from './utils/index.js';
|
|
6
|
+
export class CliBuilder {
|
|
7
|
+
packageName;
|
|
8
|
+
logger;
|
|
9
|
+
constructor(packageName = 'poet') {
|
|
10
|
+
this.packageName = packageName;
|
|
11
|
+
this.logger = new ConsoleLogger();
|
|
12
|
+
}
|
|
13
|
+
build() {
|
|
14
|
+
const versionService = new VersionService(this.packageName);
|
|
15
|
+
const portService = new PortService(this.logger);
|
|
16
|
+
const templateService = new TemplateService();
|
|
17
|
+
const openApiCheckService = new OpenApiCheckService(this.logger);
|
|
18
|
+
const accessibilityCheckService = new AccessibilityCheckService();
|
|
19
|
+
const linkService = new LinkService(this.logger);
|
|
20
|
+
const updateService = new UpdateService(this.logger, versionService, this.packageName);
|
|
21
|
+
const devCommand = new DevCommand(this.logger, versionService, portService, this.packageName);
|
|
22
|
+
const initCommand = new InitCommand(this.logger, templateService, this.packageName);
|
|
23
|
+
const checkCommand = new CheckCommand(this.logger, openApiCheckService, accessibilityCheckService, this.packageName);
|
|
24
|
+
const linkCommand = new LinkCommand(this.logger, linkService, this.packageName);
|
|
25
|
+
const updateCommand = new UpdateCommand(this.logger, updateService, this.packageName);
|
|
26
|
+
return (yargs(hideBin(process.argv))
|
|
27
|
+
.scriptName(this.packageName)
|
|
28
|
+
.command('dev', 'initialize a local preview environment', (yargs) => yargs
|
|
29
|
+
.option('port', {
|
|
30
|
+
type: 'number',
|
|
31
|
+
description: 'port to run the preview server on',
|
|
32
|
+
default: 3000,
|
|
33
|
+
})
|
|
34
|
+
.option('open', {
|
|
35
|
+
type: 'boolean',
|
|
36
|
+
default: true,
|
|
37
|
+
description: 'open a local preview in the browser',
|
|
38
|
+
})
|
|
39
|
+
.option('local-schema', {
|
|
40
|
+
type: 'boolean',
|
|
41
|
+
default: false,
|
|
42
|
+
hidden: true,
|
|
43
|
+
description: 'use a locally hosted schema file (note: only https protocol is supported in production)',
|
|
44
|
+
})
|
|
45
|
+
.option('client-version', {
|
|
46
|
+
type: 'string',
|
|
47
|
+
hidden: true,
|
|
48
|
+
description: 'the version of the client to use for cli testing',
|
|
49
|
+
})
|
|
50
|
+
.option('groups', {
|
|
51
|
+
type: 'array',
|
|
52
|
+
description: 'Mock user groups for local development and testing',
|
|
53
|
+
example: '--groups admin user',
|
|
54
|
+
})
|
|
55
|
+
.option('disable-openapi', {
|
|
56
|
+
type: 'boolean',
|
|
57
|
+
default: false,
|
|
58
|
+
description: 'Disable OpenAPI file generation',
|
|
59
|
+
}), async (argv) => {
|
|
60
|
+
try {
|
|
61
|
+
await devCommand.run(argv);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
this.logger.error(error instanceof Error ? error.message : 'Unknown error');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
.command(['new [directory]', 'init [directory]'], 'Create a new Poetora documentation site', (yargs) => yargs.positional('directory', {
|
|
69
|
+
describe: 'The directory to initialize your documentation',
|
|
70
|
+
type: 'string',
|
|
71
|
+
default: '.',
|
|
72
|
+
}), async (argv) => {
|
|
73
|
+
try {
|
|
74
|
+
await initCommand.run({ directory: argv.directory });
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
this.logger.error(error instanceof Error ? error.message : 'Unknown error');
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
.command('openapi-check <filename>', 'check if an OpenAPI spec is valid', (yargs) => yargs
|
|
82
|
+
.positional('filename', {
|
|
83
|
+
describe: 'the filename of the OpenAPI spec (e.g. ./openapi.yaml) or the URL to the OpenAPI spec',
|
|
84
|
+
type: 'string',
|
|
85
|
+
demandOption: true,
|
|
86
|
+
})
|
|
87
|
+
.option('local-schema', {
|
|
88
|
+
type: 'boolean',
|
|
89
|
+
default: false,
|
|
90
|
+
description: 'use a locally hosted schema file (note: only https protocol is supported in production)',
|
|
91
|
+
}), async (argv) => {
|
|
92
|
+
try {
|
|
93
|
+
await checkCommand.checkOpenApi({
|
|
94
|
+
filename: argv.filename,
|
|
95
|
+
localSchema: argv.localSchema,
|
|
96
|
+
});
|
|
97
|
+
process.exit(0);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
this.logger.error(error instanceof Error ? error.message : 'Unknown error');
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
.command(['a11y', 'accessibility-check', 'a11y-check', 'accessibility'], 'check for accessibility issues in documentation', () => undefined, async () => {
|
|
105
|
+
try {
|
|
106
|
+
const exitCode = await checkCommand.checkAccessibility();
|
|
107
|
+
process.exit(exitCode);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
this.logger.error(error instanceof Error ? error.message : 'Unknown error');
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
.command('broken-links', 'check for invalid internal links', () => undefined, async () => {
|
|
115
|
+
try {
|
|
116
|
+
const brokenLinks = await linkCommand.checkBrokenLinks();
|
|
117
|
+
const hasBrokenLinks = Object.keys(brokenLinks).length > 0;
|
|
118
|
+
process.exit(hasBrokenLinks ? 1 : 0);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
this.logger.error(error instanceof Error ? error.message : 'Unknown error');
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
.command('rename <from> <to>', 'rename a file and update all internal link references', (yargs) => yargs
|
|
126
|
+
.positional('from', {
|
|
127
|
+
describe: 'the file to rename',
|
|
128
|
+
type: 'string',
|
|
129
|
+
})
|
|
130
|
+
.positional('to', {
|
|
131
|
+
describe: 'the new name for the file',
|
|
132
|
+
type: 'string',
|
|
133
|
+
})
|
|
134
|
+
.demandOption(['from', 'to'])
|
|
135
|
+
.option('force', {
|
|
136
|
+
type: 'boolean',
|
|
137
|
+
default: false,
|
|
138
|
+
description: 'rename files and skip errors',
|
|
139
|
+
})
|
|
140
|
+
.epilog(`example: \`${this.packageName} rename introduction.mdx overview.mdx\``), async (argv) => {
|
|
141
|
+
try {
|
|
142
|
+
await linkCommand.renameFile({
|
|
143
|
+
from: argv.from,
|
|
144
|
+
to: argv.to,
|
|
145
|
+
force: argv.force,
|
|
146
|
+
});
|
|
147
|
+
process.exit(0);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
this.logger.error(error instanceof Error ? error.message : 'Unknown error');
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
.command('update', 'update the CLI to the latest version', () => undefined, async () => {
|
|
155
|
+
try {
|
|
156
|
+
await updateCommand.run({});
|
|
157
|
+
process.exit(0);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
this.logger.error(error instanceof Error ? error.message : 'Unknown error');
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
.command(['version', 'v'], 'display the current version of the CLI and client', () => undefined, async () => {
|
|
165
|
+
const versions = versionService.getVersions();
|
|
166
|
+
this.logger.log(`cli version: ${versions.cli}`);
|
|
167
|
+
this.logger.log(`client version: ${versions.client}`);
|
|
168
|
+
process.exit(0);
|
|
169
|
+
})
|
|
170
|
+
.strictCommands()
|
|
171
|
+
.demandCommand(1, 'unknown command. see above for the list of supported commands.')
|
|
172
|
+
.alias('h', 'help')
|
|
173
|
+
.alias('v', 'version'));
|
|
174
|
+
}
|
|
175
|
+
async run() {
|
|
176
|
+
await this.build().parseAsync();
|
|
177
|
+
}
|
|
178
|
+
}
|
package/bin/cli.d.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
$0: string;
|
|
7
|
-
} | Promise<{
|
|
8
|
-
[x: string]: unknown;
|
|
9
|
-
_: (string | number)[];
|
|
10
|
-
$0: string;
|
|
11
|
-
}>;
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export interface CliOptions {
|
|
3
|
+
packageName: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const cli: (options: CliOptions) => void;
|
package/bin/cli.js
CHANGED
|
@@ -1,201 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import { accessibilityCheck } from './accessibilityCheck.js';
|
|
10
|
-
import { checkPort, checkNodeVersion, getVersions, suppressConsoleWarnings, terminate, readLocalOpenApiFile, } from './helpers.js';
|
|
11
|
-
import { init } from './init.js';
|
|
12
|
-
import { mdxLinter } from './mdxLinter.js';
|
|
13
|
-
import { update } from './update.js';
|
|
14
|
-
export const cli = ({ packageName = 'poet' }) => {
|
|
15
|
-
render(_jsx(Logs, {}));
|
|
16
|
-
return (yargs(hideBin(process.argv))
|
|
17
|
-
.scriptName(packageName)
|
|
18
|
-
.middleware(checkNodeVersion)
|
|
19
|
-
.middleware(suppressConsoleWarnings)
|
|
20
|
-
.command('dev', 'initialize a local preview environment', (yargs) => yargs
|
|
21
|
-
.option('open', {
|
|
22
|
-
type: 'boolean',
|
|
23
|
-
default: true,
|
|
24
|
-
description: 'open a local preview in the browser',
|
|
25
|
-
})
|
|
26
|
-
.option('local-schema', {
|
|
27
|
-
type: 'boolean',
|
|
28
|
-
default: false,
|
|
29
|
-
hidden: true,
|
|
30
|
-
description: 'use a locally hosted schema file (note: only https protocol is supported in production)',
|
|
31
|
-
})
|
|
32
|
-
.option('client-version', {
|
|
33
|
-
type: 'string',
|
|
34
|
-
hidden: true,
|
|
35
|
-
description: 'the version of the client to use for cli testing',
|
|
36
|
-
})
|
|
37
|
-
.option('groups', {
|
|
38
|
-
type: 'array',
|
|
39
|
-
description: 'Mock user groups for local development and testing',
|
|
40
|
-
example: '--groups admin user',
|
|
41
|
-
})
|
|
42
|
-
.option('disable-openapi', {
|
|
43
|
-
type: 'boolean',
|
|
44
|
-
default: false,
|
|
45
|
-
description: 'Disable OpenAPI file generation',
|
|
46
|
-
})
|
|
47
|
-
.usage('usage: poetora dev [options]')
|
|
48
|
-
.example('poetora dev', 'run with default settings (opens in browser)')
|
|
49
|
-
.example('poetora dev --no-open', 'run without opening in browser'), async (argv) => {
|
|
50
|
-
let nodeVersionString = process.version;
|
|
51
|
-
if (nodeVersionString.charAt(0) === 'v') {
|
|
52
|
-
nodeVersionString = nodeVersionString.slice(1);
|
|
53
|
-
}
|
|
54
|
-
const versionArr = nodeVersionString.split('.');
|
|
55
|
-
const majorVersion = parseInt(versionArr[0], 10);
|
|
56
|
-
const minorVersion = parseInt(versionArr[1], 10);
|
|
57
|
-
if (majorVersion >= 25) {
|
|
58
|
-
addLog(_jsx(ErrorLog, { message: "poet dev is not supported on node versions 25+. Please downgrade to an LTS node version." }));
|
|
59
|
-
await terminate(1);
|
|
60
|
-
}
|
|
61
|
-
if (majorVersion < 20 || (majorVersion === 20 && minorVersion < 17)) {
|
|
62
|
-
addLog(_jsx(ErrorLog, { message: "poet dev is not supported on node versions below 20.17 Please upgrade to an LTS node version." }));
|
|
63
|
-
await terminate(1);
|
|
64
|
-
}
|
|
65
|
-
const port = await checkPort(argv);
|
|
66
|
-
const { cli: cliVersion } = getVersions();
|
|
67
|
-
if (port != undefined) {
|
|
68
|
-
await dev({
|
|
69
|
-
...argv,
|
|
70
|
-
port,
|
|
71
|
-
packageName,
|
|
72
|
-
cliVersion,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
addLog(_jsx(ErrorLog, { message: "no available port found" }));
|
|
77
|
-
await terminate(1);
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
.command('openapi-check <filename>', 'check if an OpenAPI spec is valid', (yargs) => yargs
|
|
81
|
-
.positional('filename', {
|
|
82
|
-
describe: 'the filename of the OpenAPI spec (e.g. ./openapi.yaml) or the URL to the OpenAPI spec (e.g. https://petstore3.swagger.io/api/v3/openapi.json)',
|
|
83
|
-
type: 'string',
|
|
84
|
-
demandOption: true,
|
|
85
|
-
})
|
|
86
|
-
.option('local-schema', {
|
|
87
|
-
type: 'boolean',
|
|
88
|
-
default: false,
|
|
89
|
-
description: 'use a locally hosted schema file (note: only https protocol is supported in production)',
|
|
90
|
-
}), async ({ filename, 'local-schema': localSchema }) => {
|
|
91
|
-
try {
|
|
92
|
-
if (isAllowedLocalSchemaUrl(filename, localSchema)) {
|
|
93
|
-
await getOpenApiDocumentFromUrl(filename);
|
|
94
|
-
addLog(_jsx(SuccessLog, { message: "OpenAPI definition is valid." }));
|
|
95
|
-
await terminate(0);
|
|
96
|
-
}
|
|
97
|
-
if (filename.startsWith('http://') && !localSchema) {
|
|
98
|
-
addLog(_jsx(WarningLog, { message: "include the --local-schema flag to check locally hosted OpenAPI files" }));
|
|
99
|
-
addLog(_jsx(WarningLog, { message: "only https protocol is supported in production" }));
|
|
100
|
-
await terminate(0);
|
|
101
|
-
}
|
|
102
|
-
const document = await readLocalOpenApiFile(filename);
|
|
103
|
-
if (!document) {
|
|
104
|
-
throw new Error('failed to parse OpenAPI spec: could not parse file correctly, please check for any syntax errors.');
|
|
105
|
-
}
|
|
106
|
-
await validate(document);
|
|
107
|
-
addLog(_jsx(SuccessLog, { message: "OpenAPI definition is valid." }));
|
|
108
|
-
}
|
|
109
|
-
catch (err) {
|
|
110
|
-
if (err && typeof err === 'object' && 'code' in err && err.code === 'ENOENT') {
|
|
111
|
-
addLog(_jsx(ErrorLog, { message: `file not found, please check the path provided: ${filename}` }));
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
addLog(_jsx(ErrorLog, { message: err instanceof Error ? err.message : 'unknown error' }));
|
|
115
|
-
}
|
|
116
|
-
await terminate(1);
|
|
117
|
-
}
|
|
118
|
-
await terminate(0);
|
|
119
|
-
})
|
|
120
|
-
.command('broken-links', 'check for invalid internal links', () => undefined, async () => {
|
|
121
|
-
addLog(_jsx(SpinnerLog, { message: "checking for broken links..." }));
|
|
122
|
-
try {
|
|
123
|
-
const brokenLinks = await getBrokenInternalLinks();
|
|
124
|
-
if (brokenLinks.length === 0) {
|
|
125
|
-
clearLogs();
|
|
126
|
-
addLog(_jsx(SuccessLog, { message: "no broken links found" }));
|
|
127
|
-
await terminate(0);
|
|
128
|
-
}
|
|
129
|
-
const brokenLinksByFile = {};
|
|
130
|
-
brokenLinks.forEach((mdxPath) => {
|
|
131
|
-
const filename = path.join(mdxPath.relativeDir, mdxPath.filename);
|
|
132
|
-
const brokenLinksForFile = brokenLinksByFile[filename];
|
|
133
|
-
if (brokenLinksForFile) {
|
|
134
|
-
brokenLinksForFile.push(mdxPath.originalPath);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
brokenLinksByFile[filename] = [mdxPath.originalPath];
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
clearLogs();
|
|
141
|
-
addLog(_jsx(BrokenLinksLog, { brokenLinksByFile: brokenLinksByFile }));
|
|
142
|
-
}
|
|
143
|
-
catch (err) {
|
|
144
|
-
addLog(_jsx(ErrorLog, { message: err instanceof Error ? err.message : 'unknown error' }));
|
|
145
|
-
await terminate(1);
|
|
146
|
-
}
|
|
147
|
-
await terminate(1);
|
|
148
|
-
})
|
|
149
|
-
.command('rename <from> <to>', 'rename a file and update all internal link references', (yargs) => yargs
|
|
150
|
-
.positional('from', {
|
|
151
|
-
describe: 'the file to rename',
|
|
152
|
-
type: 'string',
|
|
153
|
-
})
|
|
154
|
-
.positional('to', {
|
|
155
|
-
describe: 'the new name for the file',
|
|
156
|
-
type: 'string',
|
|
157
|
-
})
|
|
158
|
-
.demandOption(['from', 'to'])
|
|
159
|
-
.option('force', {
|
|
160
|
-
type: 'boolean',
|
|
161
|
-
default: false,
|
|
162
|
-
description: 'rename files and skip errors',
|
|
163
|
-
})
|
|
164
|
-
.epilog('example: `poetora rename introduction.mdx overview.mdx`'), async ({ from, to, force }) => {
|
|
165
|
-
await renameFilesAndUpdateLinksInContent(from, to, force);
|
|
166
|
-
await terminate(0);
|
|
167
|
-
})
|
|
168
|
-
.command('update', 'update the CLI to the latest version', () => undefined, async () => {
|
|
169
|
-
await update({ packageName });
|
|
170
|
-
await terminate(0);
|
|
171
|
-
})
|
|
172
|
-
.command(['a11y', 'accessibility-check', 'a11y-check', 'accessibility'], 'check for accessibility issues in documentation', () => undefined, async () => {
|
|
173
|
-
const accessibilityCheckTerminateCode = await accessibilityCheck();
|
|
174
|
-
const mdxLinterTerminateCode = await mdxLinter();
|
|
175
|
-
await terminate(accessibilityCheckTerminateCode || mdxLinterTerminateCode);
|
|
176
|
-
})
|
|
177
|
-
.command(['version', 'v'], 'display the current version of the CLI and client', () => undefined, async () => {
|
|
178
|
-
const { cli, client } = getVersions();
|
|
179
|
-
addLog(_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "green", children: "cli version" }), ' ', cli] }));
|
|
180
|
-
addLog(_jsxs(Text, { children: [_jsx(Text, { bold: true, color: "green", children: "client version" }), ' ', client] }));
|
|
181
|
-
})
|
|
182
|
-
.command('new [directory]', 'Create a new Poetora documentation site', (yargs) => yargs.positional('directory', {
|
|
183
|
-
describe: 'The directory to initialize your documentation',
|
|
184
|
-
type: 'string',
|
|
185
|
-
default: '.',
|
|
186
|
-
}), async ({ directory }) => {
|
|
187
|
-
try {
|
|
188
|
-
await init(directory);
|
|
189
|
-
await terminate(0);
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
addLog(_jsx(ErrorLog, { message: error instanceof Error ? error.message : 'error occurred' }));
|
|
193
|
-
await terminate(1);
|
|
194
|
-
}
|
|
195
|
-
})
|
|
196
|
-
.strictCommands()
|
|
197
|
-
.demandCommand(1, 'unknown command. see above for the list of supported commands.')
|
|
198
|
-
.alias('h', 'help')
|
|
199
|
-
.alias('v', 'version')
|
|
200
|
-
.parse());
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { CliBuilder } from './cli-builder.js';
|
|
3
|
+
export const cli = (options) => {
|
|
4
|
+
const builder = new CliBuilder(options.packageName);
|
|
5
|
+
builder.run().catch((error) => {
|
|
6
|
+
console.error('Fatal error:', error);
|
|
7
|
+
process.exit(1);
|
|
8
|
+
});
|
|
201
9
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ILogger } from '../utils/index.js';
|
|
2
|
+
export declare abstract class BaseCommand<TOptions = unknown, TResult = void> {
|
|
3
|
+
protected readonly logger: ILogger;
|
|
4
|
+
protected readonly packageName: string;
|
|
5
|
+
abstract readonly name: string;
|
|
6
|
+
abstract readonly description: string;
|
|
7
|
+
constructor(logger: ILogger, packageName?: string);
|
|
8
|
+
run(options: TOptions): Promise<TResult>;
|
|
9
|
+
protected validate(_options: TOptions): Promise<void>;
|
|
10
|
+
protected abstract execute(options: TOptions): Promise<TResult>;
|
|
11
|
+
protected handleError(error: unknown): void;
|
|
12
|
+
protected exit(code: number): never;
|
|
13
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { CliError } from '../errors/index.js';
|
|
2
|
+
export class BaseCommand {
|
|
3
|
+
logger;
|
|
4
|
+
packageName;
|
|
5
|
+
constructor(logger, packageName = 'poet') {
|
|
6
|
+
this.logger = logger;
|
|
7
|
+
this.packageName = packageName;
|
|
8
|
+
}
|
|
9
|
+
async run(options) {
|
|
10
|
+
try {
|
|
11
|
+
await this.validate(options);
|
|
12
|
+
const result = await this.execute(options);
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
this.handleError(error);
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async validate(_options) {
|
|
21
|
+
}
|
|
22
|
+
handleError(error) {
|
|
23
|
+
if (error instanceof CliError) {
|
|
24
|
+
this.logger.error(error.message);
|
|
25
|
+
}
|
|
26
|
+
else if (error instanceof Error) {
|
|
27
|
+
this.logger.error(error.message);
|
|
28
|
+
if (process.env.DEBUG === 'true') {
|
|
29
|
+
console.error(error.stack);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
this.logger.error('An unexpected error occurred');
|
|
34
|
+
console.error(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exit(code) {
|
|
38
|
+
process.exit(code);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AccessibilityCheckService, OpenApiCheckService } from '../services/index.js';
|
|
2
|
+
import type { OpenApiCheckOptions } from '../types/index.js';
|
|
3
|
+
import type { ILogger } from '../utils/index.js';
|
|
4
|
+
import { BaseCommand } from './base.command.js';
|
|
5
|
+
export declare class CheckCommand extends BaseCommand {
|
|
6
|
+
private readonly openApiCheckService;
|
|
7
|
+
private readonly accessibilityCheckService;
|
|
8
|
+
readonly name = "check";
|
|
9
|
+
readonly description = "check OpenAPI specs or accessibility";
|
|
10
|
+
constructor(logger: ILogger, openApiCheckService: OpenApiCheckService, accessibilityCheckService: AccessibilityCheckService, packageName?: string);
|
|
11
|
+
checkOpenApi(options: OpenApiCheckOptions): Promise<void>;
|
|
12
|
+
checkAccessibility(): Promise<number>;
|
|
13
|
+
protected execute(options: OpenApiCheckOptions): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseCommand } from './base.command.js';
|
|
2
|
+
export class CheckCommand extends BaseCommand {
|
|
3
|
+
openApiCheckService;
|
|
4
|
+
accessibilityCheckService;
|
|
5
|
+
name = 'check';
|
|
6
|
+
description = 'check OpenAPI specs or accessibility';
|
|
7
|
+
constructor(logger, openApiCheckService, accessibilityCheckService, packageName = 'poet') {
|
|
8
|
+
super(logger, packageName);
|
|
9
|
+
this.openApiCheckService = openApiCheckService;
|
|
10
|
+
this.accessibilityCheckService = accessibilityCheckService;
|
|
11
|
+
}
|
|
12
|
+
async checkOpenApi(options) {
|
|
13
|
+
await this.openApiCheckService.validateSpec(options.filename, options.localSchema);
|
|
14
|
+
}
|
|
15
|
+
async checkAccessibility() {
|
|
16
|
+
return await this.accessibilityCheckService.checkAccessibility();
|
|
17
|
+
}
|
|
18
|
+
async execute(options) {
|
|
19
|
+
await this.openApiCheckService.validateSpec(options.filename, options.localSchema);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PortService, VersionService } from '../services/index.js';
|
|
2
|
+
import type { DevOptions } from '../types/index.js';
|
|
3
|
+
import type { ILogger } from '../utils/index.js';
|
|
4
|
+
import { BaseCommand } from './base.command.js';
|
|
5
|
+
export declare class DevCommand extends BaseCommand {
|
|
6
|
+
private readonly versionService;
|
|
7
|
+
private readonly portService;
|
|
8
|
+
readonly name = "dev";
|
|
9
|
+
readonly description = "initialize a local preview environment";
|
|
10
|
+
constructor(logger: ILogger, versionService: VersionService, portService: PortService, packageName?: string);
|
|
11
|
+
protected validate(_options: DevOptions): Promise<void>;
|
|
12
|
+
protected execute(options: DevOptions): Promise<void>;
|
|
13
|
+
}
|