@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.
Files changed (117) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/LICENSE +93 -0
  3. package/bin/accessibility.js +2 -2
  4. package/bin/cli-builder.d.ts +8 -0
  5. package/bin/cli-builder.js +178 -0
  6. package/bin/cli.d.ts +5 -11
  7. package/bin/cli.js +8 -200
  8. package/bin/commands/base.command.d.ts +13 -0
  9. package/bin/commands/base.command.js +40 -0
  10. package/bin/commands/check.command.d.ts +14 -0
  11. package/bin/commands/check.command.js +21 -0
  12. package/bin/commands/dev.command.d.ts +13 -0
  13. package/bin/commands/dev.command.js +40 -0
  14. package/bin/commands/index.d.ts +6 -0
  15. package/bin/commands/index.js +6 -0
  16. package/bin/commands/init.command.d.ts +16 -0
  17. package/bin/commands/init.command.js +88 -0
  18. package/bin/commands/link.command.d.ts +13 -0
  19. package/bin/commands/link.command.js +19 -0
  20. package/bin/commands/update.command.d.ts +10 -0
  21. package/bin/commands/update.command.js +13 -0
  22. package/bin/constants.js +1 -1
  23. package/bin/errors/cli-error.d.ts +26 -0
  24. package/bin/errors/cli-error.js +53 -0
  25. package/bin/errors/index.d.ts +1 -0
  26. package/bin/errors/index.js +1 -0
  27. package/bin/index.d.ts +1 -1
  28. package/bin/index.js +6 -6
  29. package/bin/mdxAccessibility.js +2 -2
  30. package/bin/services/accessibility-check.service.d.ts +10 -0
  31. package/bin/services/accessibility-check.service.js +144 -0
  32. package/bin/services/index.d.ts +7 -0
  33. package/bin/services/index.js +7 -0
  34. package/bin/services/link.service.d.ts +7 -0
  35. package/bin/services/link.service.js +40 -0
  36. package/bin/services/openapi-check.service.d.ts +7 -0
  37. package/bin/services/openapi-check.service.js +43 -0
  38. package/bin/services/port.service.d.ts +7 -0
  39. package/bin/services/port.service.js +26 -0
  40. package/bin/services/template.service.d.ts +22 -0
  41. package/bin/services/template.service.js +127 -0
  42. package/bin/services/update.service.d.ts +10 -0
  43. package/bin/services/update.service.js +57 -0
  44. package/bin/services/version.service.d.ts +16 -0
  45. package/bin/services/version.service.js +102 -0
  46. package/bin/types/common.d.ts +38 -0
  47. package/bin/types/common.js +21 -0
  48. package/bin/types/index.d.ts +2 -0
  49. package/bin/types/index.js +2 -0
  50. package/bin/types/options.d.ts +23 -0
  51. package/bin/types/options.js +1 -0
  52. package/bin/utils/console-logger.d.ts +16 -0
  53. package/bin/utils/console-logger.js +65 -0
  54. package/bin/utils/index.d.ts +2 -0
  55. package/bin/utils/index.js +2 -0
  56. package/bin/utils/logger.interface.d.ts +15 -0
  57. package/bin/utils/logger.interface.js +1 -0
  58. package/package.json +29 -29
  59. package/src/accessibility.ts +2 -2
  60. package/src/cli-builder.ts +267 -0
  61. package/src/cli.ts +15 -0
  62. package/src/commands/__tests__/base.command.test.ts +145 -0
  63. package/src/commands/__tests__/dev.command.test.ts +241 -0
  64. package/src/commands/__tests__/init.command.test.ts +281 -0
  65. package/{__test__ → src/commands/__tests__}/utils.ts +1 -1
  66. package/src/commands/base.command.ts +97 -0
  67. package/src/commands/check.command.ts +40 -0
  68. package/src/commands/dev.command.ts +63 -0
  69. package/src/commands/index.ts +6 -0
  70. package/src/commands/init.command.ts +125 -0
  71. package/src/commands/link.command.ts +39 -0
  72. package/src/commands/update.command.ts +23 -0
  73. package/src/constants.ts +1 -1
  74. package/src/errors/cli-error.ts +83 -0
  75. package/src/errors/index.ts +1 -0
  76. package/src/index.ts +6 -6
  77. package/src/mdxAccessibility.ts +3 -4
  78. package/src/services/__tests__/port.service.test.ts +83 -0
  79. package/src/services/__tests__/template.service.test.ts +234 -0
  80. package/src/services/__tests__/version.service.test.ts +165 -0
  81. package/src/services/accessibility-check.service.ts +226 -0
  82. package/src/services/index.ts +7 -0
  83. package/src/services/link.service.ts +65 -0
  84. package/src/services/openapi-check.service.ts +68 -0
  85. package/src/services/port.service.ts +47 -0
  86. package/src/services/template.service.ts +203 -0
  87. package/src/services/update.service.ts +76 -0
  88. package/src/services/version.service.ts +161 -0
  89. package/src/types/common.ts +53 -0
  90. package/src/types/index.ts +2 -0
  91. package/src/types/options.ts +42 -0
  92. package/src/utils/console-logger.ts +114 -0
  93. package/src/utils/index.ts +2 -0
  94. package/src/utils/logger.interface.ts +70 -0
  95. package/tsconfig.build.json +2 -1
  96. package/tsconfig.json +1 -1
  97. package/.prettierignore +0 -2
  98. package/__test__/brokenLinks.test.ts +0 -93
  99. package/__test__/checkPort.test.ts +0 -92
  100. package/__test__/openApiCheck.test.ts +0 -127
  101. package/__test__/update.test.ts +0 -108
  102. package/bin/accessibilityCheck.d.ts +0 -2
  103. package/bin/accessibilityCheck.js +0 -70
  104. package/bin/helpers.d.ts +0 -17
  105. package/bin/helpers.js +0 -104
  106. package/bin/init.d.ts +0 -1
  107. package/bin/init.js +0 -73
  108. package/bin/mdxLinter.d.ts +0 -2
  109. package/bin/mdxLinter.js +0 -45
  110. package/bin/update.d.ts +0 -3
  111. package/bin/update.js +0 -32
  112. package/src/accessibilityCheck.tsx +0 -145
  113. package/src/cli.tsx +0 -302
  114. package/src/helpers.tsx +0 -131
  115. package/src/init.tsx +0 -93
  116. package/src/mdxLinter.tsx +0 -88
  117. package/src/update.tsx +0 -37
@@ -1,145 +0,0 @@
1
- import { getConfigObj, getConfigPath } from '@poetora/prebuild';
2
- import { addLog, ErrorLog, WarningLog } from '@poetora/previewing';
3
- import { getBackgroundColors } from '@poetora/shared';
4
- import { Text } from 'ink';
5
-
6
- import { checkDocsColors, type AccessibilityCheckResult } from './accessibility.js';
7
- import { ContrastResult } from './accessibility.js';
8
- import { CMD_EXEC_PATH } from './constants.js';
9
-
10
- export type TerminateCode = 0 | 1;
11
-
12
- export const accessibilityCheck = async (): Promise<TerminateCode> => {
13
- try {
14
- const docsConfigPath = await getConfigPath(CMD_EXEC_PATH);
15
-
16
- if (!docsConfigPath) {
17
- addLog(
18
- <ErrorLog message="No configuration file found. Please run this command from a directory with a docs.json file." />
19
- );
20
- return 1;
21
- }
22
-
23
- const config = await getConfigObj(CMD_EXEC_PATH);
24
-
25
- if (!config.colors) {
26
- addLog(<WarningLog message="No colors section found in configuration file" />);
27
- return 0;
28
- }
29
-
30
- const { colors, navigation } = config;
31
-
32
- const { lightHex, darkHex } = getBackgroundColors(config);
33
-
34
- const results: AccessibilityCheckResult = checkDocsColors(
35
- colors,
36
- { lightHex, darkHex },
37
- navigation
38
- );
39
-
40
- const displayContrastResult = (
41
- result: ContrastResult | null,
42
- label: string,
43
- prefix: string = ''
44
- ) => {
45
- if (!result) return;
46
-
47
- const { recommendation, message } = result;
48
- const icon =
49
- recommendation === 'pass' ? 'PASS' : recommendation === 'warning' ? 'WARN' : 'FAIL';
50
- const color =
51
- recommendation === 'pass' ? 'green' : recommendation === 'warning' ? 'yellow' : 'red';
52
-
53
- addLog(
54
- <Text>
55
- <Text bold={prefix === ''}>
56
- {prefix}
57
- {label}:{' '}
58
- </Text>
59
- <Text color={color}>
60
- {icon} {message}
61
- </Text>
62
- </Text>
63
- );
64
- };
65
-
66
- addLog(
67
- <Text bold color="cyan">
68
- Checking color accessibility...
69
- </Text>
70
- );
71
- addLog(<Text></Text>);
72
-
73
- displayContrastResult(
74
- results.primaryContrast,
75
- `Primary Color (${colors.primary}) vs Light Background`
76
- );
77
- displayContrastResult(
78
- results.lightContrast,
79
- `Light Color (${colors.light}) vs Dark Background`
80
- );
81
- displayContrastResult(results.darkContrast, `Dark Color (${colors.dark}) vs Dark Background`);
82
- displayContrastResult(
83
- results.darkOnLightContrast,
84
- `Dark Color (${colors.dark}) vs Light Background`
85
- );
86
-
87
- const anchorsWithResults = results.anchorResults.filter(
88
- (anchor) => anchor.lightContrast || anchor.darkContrast
89
- );
90
-
91
- if (anchorsWithResults.length > 0) {
92
- addLog(<Text></Text>);
93
- addLog(
94
- <Text bold color="cyan">
95
- Navigation Anchors:
96
- </Text>
97
- );
98
-
99
- for (const anchor of anchorsWithResults) {
100
- addLog(<Text bold> {anchor.name}:</Text>);
101
- displayContrastResult(anchor.lightContrast, 'Light variant vs Light Background', ' ');
102
- displayContrastResult(anchor.darkContrast, 'Dark variant vs Dark Background', ' ');
103
- }
104
- }
105
-
106
- addLog(<Text></Text>);
107
- const overallIcon =
108
- results.overallScore === 'pass'
109
- ? 'PASS'
110
- : results.overallScore === 'warning'
111
- ? 'WARN'
112
- : 'FAIL';
113
- const overallColor =
114
- results.overallScore === 'pass'
115
- ? 'green'
116
- : results.overallScore === 'warning'
117
- ? 'yellow'
118
- : 'red';
119
- const overallMessage =
120
- results.overallScore === 'pass'
121
- ? 'All colors meet accessibility standards!'
122
- : results.overallScore === 'warning'
123
- ? 'Some colors could be improved for better accessibility'
124
- : 'Some colors fail accessibility standards and should be updated';
125
-
126
- addLog(
127
- <Text>
128
- <Text bold color={overallColor}>
129
- Overall Assessment: {overallIcon} {overallMessage}
130
- </Text>
131
- </Text>
132
- );
133
-
134
- return results.overallScore === 'fail' ? 1 : 0;
135
- } catch (error) {
136
- addLog(
137
- <ErrorLog
138
- message={`Accessibility check failed: ${
139
- error instanceof Error ? error.message : 'Unknown error'
140
- }`}
141
- />
142
- );
143
- return 1;
144
- }
145
- };
package/src/cli.tsx DELETED
@@ -1,302 +0,0 @@
1
- import { getBrokenInternalLinks, renameFilesAndUpdateLinksInContent } from '@poetora/link-rot';
2
- import {
3
- addLog,
4
- dev,
5
- ErrorLog,
6
- SpinnerLog,
7
- SuccessLog,
8
- Logs,
9
- clearLogs,
10
- BrokenLinksLog,
11
- WarningLog,
12
- } from '@poetora/previewing';
13
- import { validate, getOpenApiDocumentFromUrl, isAllowedLocalSchemaUrl } from '@poetora/shared';
14
- import { render, Text } from 'ink';
15
- import path from 'path';
16
- import yargs from 'yargs';
17
- import { hideBin } from 'yargs/helpers';
18
-
19
- import { accessibilityCheck } from './accessibilityCheck.js';
20
- import {
21
- checkPort,
22
- checkNodeVersion,
23
- getVersions,
24
- suppressConsoleWarnings,
25
- terminate,
26
- readLocalOpenApiFile,
27
- } from './helpers.js';
28
- import { init } from './init.js';
29
- import { mdxLinter } from './mdxLinter.js';
30
- import { update } from './update.js';
31
-
32
- export const cli = ({ packageName = 'poet' }: { packageName?: string }) => {
33
- render(<Logs />);
34
-
35
- return (
36
- yargs(hideBin(process.argv))
37
- .scriptName(packageName)
38
- .middleware(checkNodeVersion)
39
- .middleware(suppressConsoleWarnings)
40
- .command(
41
- 'dev',
42
- 'initialize a local preview environment',
43
- (yargs) =>
44
- yargs
45
- .option('open', {
46
- type: 'boolean',
47
- default: true,
48
- description: 'open a local preview in the browser',
49
- })
50
- .option('local-schema', {
51
- type: 'boolean',
52
- default: false,
53
- hidden: true,
54
- description:
55
- 'use a locally hosted schema file (note: only https protocol is supported in production)',
56
- })
57
- .option('client-version', {
58
- type: 'string',
59
- hidden: true,
60
- description: 'the version of the client to use for cli testing',
61
- })
62
- .option('groups', {
63
- type: 'array',
64
- description: 'Mock user groups for local development and testing',
65
- example: '--groups admin user',
66
- })
67
- .option('disable-openapi', {
68
- type: 'boolean',
69
- default: false,
70
- description: 'Disable OpenAPI file generation',
71
- })
72
- .usage('usage: poetora dev [options]')
73
- .example('poetora dev', 'run with default settings (opens in browser)')
74
- .example('poetora dev --no-open', 'run without opening in browser'),
75
- async (argv) => {
76
- let nodeVersionString = process.version;
77
- if (nodeVersionString.charAt(0) === 'v') {
78
- nodeVersionString = nodeVersionString.slice(1);
79
- }
80
- const versionArr = nodeVersionString.split('.');
81
- const majorVersion = parseInt(versionArr[0]!, 10);
82
- const minorVersion = parseInt(versionArr[1]!, 10);
83
-
84
- if (majorVersion >= 25) {
85
- addLog(
86
- <ErrorLog message="poet dev is not supported on node versions 25+. Please downgrade to an LTS node version." />
87
- );
88
- await terminate(1);
89
- }
90
-
91
- if (majorVersion < 20 || (majorVersion === 20 && minorVersion < 17)) {
92
- addLog(
93
- <ErrorLog message="poet dev is not supported on node versions below 20.17 Please upgrade to an LTS node version." />
94
- );
95
- await terminate(1);
96
- }
97
-
98
- const port = await checkPort(argv);
99
- const { cli: cliVersion } = getVersions();
100
- if (port != undefined) {
101
- await dev({
102
- ...argv,
103
- port,
104
- packageName,
105
- cliVersion,
106
- });
107
- } else {
108
- addLog(<ErrorLog message="no available port found" />);
109
- await terminate(1);
110
- }
111
- }
112
- )
113
- .command(
114
- 'openapi-check <filename>',
115
- 'check if an OpenAPI spec is valid',
116
- (yargs) =>
117
- yargs
118
- .positional('filename', {
119
- describe:
120
- '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)',
121
- type: 'string',
122
- demandOption: true,
123
- })
124
- .option('local-schema', {
125
- type: 'boolean',
126
- default: false,
127
- description:
128
- 'use a locally hosted schema file (note: only https protocol is supported in production)',
129
- }),
130
- async ({ filename, 'local-schema': localSchema }) => {
131
- try {
132
- if (isAllowedLocalSchemaUrl(filename, localSchema)) {
133
- await getOpenApiDocumentFromUrl(filename);
134
- addLog(<SuccessLog message="OpenAPI definition is valid." />);
135
- await terminate(0);
136
- }
137
-
138
- if (filename.startsWith('http://') && !localSchema) {
139
- addLog(
140
- <WarningLog message="include the --local-schema flag to check locally hosted OpenAPI files" />
141
- );
142
- addLog(<WarningLog message="only https protocol is supported in production" />);
143
- await terminate(0);
144
- }
145
-
146
- const document = await readLocalOpenApiFile(filename);
147
-
148
- if (!document) {
149
- throw new Error(
150
- 'failed to parse OpenAPI spec: could not parse file correctly, please check for any syntax errors.'
151
- );
152
- }
153
- await validate(document);
154
- addLog(<SuccessLog message="OpenAPI definition is valid." />);
155
- } catch (err) {
156
- if (err && typeof err === 'object' && 'code' in err && err.code === 'ENOENT') {
157
- addLog(
158
- <ErrorLog message={`file not found, please check the path provided: ${filename}`} />
159
- );
160
- } else {
161
- addLog(<ErrorLog message={err instanceof Error ? err.message : 'unknown error'} />);
162
- }
163
- await terminate(1);
164
- }
165
-
166
- await terminate(0);
167
- }
168
- )
169
- .command(
170
- 'broken-links',
171
- 'check for invalid internal links',
172
- () => undefined,
173
- async () => {
174
- addLog(<SpinnerLog message="checking for broken links..." />);
175
- try {
176
- const brokenLinks = await getBrokenInternalLinks();
177
- if (brokenLinks.length === 0) {
178
- clearLogs();
179
- addLog(<SuccessLog message="no broken links found" />);
180
- await terminate(0);
181
- }
182
-
183
- const brokenLinksByFile: Record<string, string[]> = {};
184
- brokenLinks.forEach((mdxPath) => {
185
- const filename = path.join(mdxPath.relativeDir, mdxPath.filename);
186
- const brokenLinksForFile = brokenLinksByFile[filename];
187
- if (brokenLinksForFile) {
188
- brokenLinksForFile.push(mdxPath.originalPath);
189
- } else {
190
- brokenLinksByFile[filename] = [mdxPath.originalPath];
191
- }
192
- });
193
- clearLogs();
194
- addLog(<BrokenLinksLog brokenLinksByFile={brokenLinksByFile} />);
195
- } catch (err) {
196
- addLog(<ErrorLog message={err instanceof Error ? err.message : 'unknown error'} />);
197
- await terminate(1);
198
- }
199
-
200
- await terminate(1);
201
- }
202
- )
203
- .command(
204
- 'rename <from> <to>',
205
- 'rename a file and update all internal link references',
206
- (yargs) =>
207
- yargs
208
- .positional('from', {
209
- describe: 'the file to rename',
210
- type: 'string',
211
- })
212
- .positional('to', {
213
- describe: 'the new name for the file',
214
- type: 'string',
215
- })
216
- .demandOption(['from', 'to'])
217
- .option('force', {
218
- type: 'boolean',
219
- default: false,
220
- description: 'rename files and skip errors',
221
- })
222
- .epilog('example: `poetora rename introduction.mdx overview.mdx`'),
223
- async ({ from, to, force }) => {
224
- await renameFilesAndUpdateLinksInContent(from, to, force);
225
- await terminate(0);
226
- }
227
- )
228
- .command(
229
- 'update',
230
- 'update the CLI to the latest version',
231
- () => undefined,
232
- async () => {
233
- await update({ packageName });
234
- await terminate(0);
235
- }
236
- )
237
- .command(
238
- ['a11y', 'accessibility-check', 'a11y-check', 'accessibility'],
239
- 'check for accessibility issues in documentation',
240
- () => undefined,
241
- async () => {
242
- const accessibilityCheckTerminateCode = await accessibilityCheck();
243
- const mdxLinterTerminateCode = await mdxLinter();
244
- await terminate(accessibilityCheckTerminateCode || mdxLinterTerminateCode);
245
- }
246
- )
247
- .command(
248
- ['version', 'v'],
249
- 'display the current version of the CLI and client',
250
- () => undefined,
251
- async () => {
252
- const { cli, client } = getVersions();
253
- addLog(
254
- <Text>
255
- <Text bold color="green">
256
- cli version
257
- </Text>{' '}
258
- {cli}
259
- </Text>
260
- );
261
- addLog(
262
- <Text>
263
- <Text bold color="green">
264
- client version
265
- </Text>{' '}
266
- {client}
267
- </Text>
268
- );
269
- }
270
- )
271
- .command(
272
- 'new [directory]',
273
- 'Create a new Poetora documentation site',
274
- (yargs) =>
275
- yargs.positional('directory', {
276
- describe: 'The directory to initialize your documentation',
277
- type: 'string',
278
- default: '.',
279
- }),
280
- async ({ directory }) => {
281
- try {
282
- await init(directory);
283
- await terminate(0);
284
- } catch (error) {
285
- addLog(
286
- <ErrorLog message={error instanceof Error ? error.message : 'error occurred'} />
287
- );
288
- await terminate(1);
289
- }
290
- }
291
- )
292
- // Print the help menu when the user enters an invalid command.
293
- .strictCommands()
294
- .demandCommand(1, 'unknown command. see above for the list of supported commands.')
295
-
296
- // Alias option flags --help = -h, default --version = -v
297
- .alias('h', 'help')
298
- .alias('v', 'version')
299
-
300
- .parse()
301
- );
302
- };
package/src/helpers.tsx DELETED
@@ -1,131 +0,0 @@
1
- import {
2
- addLog,
3
- ErrorLog,
4
- getClientVersion,
5
- InfoLog,
6
- LOCAL_LINKED_CLI_VERSION,
7
- } from '@poetora/previewing';
8
- import detect from 'detect-port';
9
- import fs from 'fs/promises';
10
- import yaml from 'js-yaml';
11
- import { exec, execSync } from 'node:child_process';
12
- import { promisify } from 'node:util';
13
- import path from 'path';
14
- import type { ArgumentsCamelCase } from 'yargs';
15
- import yargs from 'yargs';
16
-
17
- export const checkPort = async (argv: ArgumentsCamelCase): Promise<number | undefined> => {
18
- const initialPort = typeof argv.port === 'number' ? argv.port : 3000;
19
- if (initialPort === (await detect(initialPort))) return initialPort;
20
-
21
- for (let port = initialPort + 1; port < initialPort + 10; port++) {
22
- addLog(<InfoLog message={`port ${port - 1} is already in use. trying ${port} instead`} />);
23
- if (port === (await detect(port))) return port;
24
- }
25
- };
26
-
27
- export const checkNodeVersion = async () => {
28
- let nodeVersionString = process.version;
29
- if (nodeVersionString.charAt(0) === 'v') {
30
- nodeVersionString = nodeVersionString.slice(1);
31
- }
32
- const versionArr = nodeVersionString.split('.');
33
- const majorVersion = parseInt(versionArr[0]!, 10);
34
-
35
- if (majorVersion < 18) {
36
- addLog(
37
- <ErrorLog
38
- message={`poetora requires a node version >= 18.0.0 (current version ${nodeVersionString}). try removing the poetora package, upgrading node, reinstalling poetora, and running again.`}
39
- />
40
- );
41
- }
42
- };
43
-
44
- export const getCliVersion = (): string | undefined => {
45
- const y = yargs();
46
- let version = undefined;
47
- y.showVersion((s) => {
48
- version = s;
49
- return false;
50
- });
51
- if (process.env.CLI_TEST_MODE === 'true') {
52
- return 'test-cli';
53
- }
54
- // when running `npm link` the version is 'unknown'
55
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
56
- if (version === 'unknown') {
57
- version = LOCAL_LINKED_CLI_VERSION;
58
- }
59
- return version;
60
- };
61
-
62
- export const getVersions = (): {
63
- cli: string | undefined;
64
- client: string | undefined;
65
- } => {
66
- const cli = getCliVersion();
67
- const client = getClientVersion().trim();
68
- return { cli, client };
69
- };
70
-
71
- export const getLatestCliVersion = (packageName: string) => {
72
- return execSync(`npm view ${packageName} version --silent`, {
73
- encoding: 'utf-8',
74
- stdio: ['pipe', 'pipe', 'pipe'],
75
- }).trim();
76
- };
77
-
78
- export const suppressConsoleWarnings = (): void => {
79
- // Ignore tailwind warnings and punycode deprecation warning
80
- const ignoredMessages = [
81
- 'No utility classes were detected',
82
- 'https://tailwindcss.com/docs/content-configuration',
83
- 'DeprecationWarning',
84
- ];
85
- const originalConsoleError = console.error;
86
- console.error = (...args) => {
87
- const message = args.join(' ');
88
- if (ignoredMessages.some((ignoredMessage) => message.includes(ignoredMessage))) {
89
- return;
90
- }
91
- originalConsoleError.apply(console, args);
92
- };
93
- const originalConsoleWarn = console.warn;
94
- console.warn = (...args) => {
95
- const message = args.join(' ');
96
- if (ignoredMessages.some((ignoredMessage) => message.includes(ignoredMessage))) {
97
- return;
98
- }
99
- originalConsoleWarn.apply(console, args);
100
- };
101
- };
102
-
103
- export const readLocalOpenApiFile = async (
104
- filename: string
105
- ): Promise<Record<string, unknown> | undefined> => {
106
- const pathname = path.resolve(process.cwd(), filename);
107
- const file = await fs.readFile(pathname, 'utf-8');
108
- const document = yaml.load(file) as Record<string, unknown> | undefined;
109
- return document;
110
- };
111
-
112
- export const terminate = async (code: number) => {
113
- // Wait for the logs to be fully rendered before exiting
114
- await new Promise((resolve) => setTimeout(resolve, 50));
115
- process.exit(code);
116
- };
117
-
118
- export const execAsync = promisify(exec);
119
-
120
- export const detectPackageManager = async ({ packageName }: { packageName: string }) => {
121
- try {
122
- const { stdout: packagePath } = await execAsync(`which ${packageName}`);
123
- if (packagePath.includes('pnpm')) {
124
- return 'pnpm';
125
- } else {
126
- return 'npm';
127
- }
128
- } catch (error) {
129
- return 'npm';
130
- }
131
- };
package/src/init.tsx DELETED
@@ -1,93 +0,0 @@
1
- import { select, input } from '@inquirer/prompts';
2
- import { addLogs, addLog, SpinnerLog, removeLastLog } from '@poetora/previewing';
3
- import { docsConfigSchema } from '@poetora/validation';
4
- import AdmZip from 'adm-zip';
5
- import fse from 'fs-extra';
6
- import { Box, Text } from 'ink';
7
-
8
- const sendOnboardingMessage = (installDir: string) => {
9
- addLogs(
10
- <Text bold>Documentation Setup!</Text>,
11
- <Text>To see your docs run</Text>,
12
- <Box>
13
- <Text color="blue">cd</Text>
14
- <Text> {installDir}</Text>
15
- </Box>,
16
- <Text color="blue">poet dev</Text>
17
- );
18
- };
19
-
20
- export async function init(installDir: string): Promise<void> {
21
- await fse.ensureDir(installDir);
22
- const dirContents = await fse.readdir(installDir).catch(() => []);
23
- if (dirContents.length > 0) {
24
- const choice = await select({
25
- message: `Directory ${installDir} is not empty. What would you like to do?`,
26
- choices: [
27
- { name: 'Create in a subdirectory', value: 'subdir' },
28
- { name: 'Overwrite current directory (may lose contents)', value: 'overwrite' },
29
- { name: 'Cancel', value: 'cancel' },
30
- ],
31
- });
32
-
33
- if (choice === 'cancel') {
34
- return;
35
- }
36
-
37
- if (choice === 'subdir') {
38
- const subdir = await input({
39
- message: 'Subdirectory name:',
40
- default: 'docs',
41
- });
42
- if (!subdir || subdir.trim() === '') {
43
- throw new Error('Subdirectory name cannot be empty');
44
- }
45
- installDir = installDir === '.' ? subdir : `${installDir}/${subdir}`;
46
- await fse.ensureDir(installDir);
47
- }
48
- }
49
-
50
- const defaultProject = installDir == '.' ? 'Poetora' : installDir;
51
- const projectName = await input({
52
- message: 'Project Name',
53
- default: defaultProject,
54
- });
55
-
56
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
- const themes = docsConfigSchema.options.map((option: any) => {
58
- return option.shape.theme._def.value;
59
- });
60
-
61
- const theme = await select({
62
- message: 'Theme',
63
- choices: themes.map((t: string) => ({
64
- name: t,
65
- value: t,
66
- })),
67
- });
68
-
69
- addLog(<SpinnerLog message="downloading starter template..." />);
70
- const response = await fetch('https://github.com/poetora/starter/archive/refs/heads/main.zip');
71
- const buffer = await response.arrayBuffer();
72
- await fse.writeFile(installDir + '/starter.zip', Buffer.from(buffer));
73
- removeLastLog();
74
-
75
- addLog(<SpinnerLog message="extracting..." />);
76
- new AdmZip(installDir + '/starter.zip').extractAllTo(installDir, true);
77
- removeLastLog();
78
-
79
- await fse.copy(installDir + '/starter-main', installDir, {
80
- overwrite: true,
81
- filter: (src: string) => !src.includes('starter-main/starter-main'),
82
- });
83
- await fse.remove(installDir + '/starter.zip');
84
- await fse.remove(installDir + '/starter-main');
85
-
86
- const docsJsonPath = installDir + '/docs.json';
87
- const docsConfig = await fse.readJson(docsJsonPath);
88
- docsConfig.theme = theme;
89
- docsConfig.name = projectName;
90
- await fse.writeJson(docsJsonPath, docsConfig, { spaces: 2 });
91
-
92
- sendOnboardingMessage(installDir);
93
- }