@appium/docutils 0.4.12 → 1.0.1

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 (75) hide show
  1. package/base-mkdocs.yml +45 -5
  2. package/build/lib/builder/deploy.d.ts +4 -4
  3. package/build/lib/builder/deploy.d.ts.map +1 -1
  4. package/build/lib/builder/deploy.js +5 -4
  5. package/build/lib/builder/deploy.js.map +1 -1
  6. package/build/lib/builder/index.d.ts +0 -2
  7. package/build/lib/builder/index.d.ts.map +1 -1
  8. package/build/lib/builder/index.js +0 -2
  9. package/build/lib/builder/index.js.map +1 -1
  10. package/build/lib/builder/site.d.ts +2 -2
  11. package/build/lib/builder/site.js +2 -2
  12. package/build/lib/cli/command/build.d.ts +8 -45
  13. package/build/lib/cli/command/build.d.ts.map +1 -1
  14. package/build/lib/cli/command/build.js +11 -56
  15. package/build/lib/cli/command/build.js.map +1 -1
  16. package/build/lib/cli/command/init.d.ts +0 -27
  17. package/build/lib/cli/command/init.d.ts.map +1 -1
  18. package/build/lib/cli/command/init.js +0 -27
  19. package/build/lib/cli/command/init.js.map +1 -1
  20. package/build/lib/cli/command/validate.d.ts +0 -24
  21. package/build/lib/cli/command/validate.d.ts.map +1 -1
  22. package/build/lib/cli/command/validate.js +2 -26
  23. package/build/lib/cli/command/validate.js.map +1 -1
  24. package/build/lib/constants.d.ts +3 -14
  25. package/build/lib/constants.d.ts.map +1 -1
  26. package/build/lib/constants.js +4 -15
  27. package/build/lib/constants.js.map +1 -1
  28. package/build/lib/fs.d.ts +0 -29
  29. package/build/lib/fs.d.ts.map +1 -1
  30. package/build/lib/fs.js +4 -57
  31. package/build/lib/fs.js.map +1 -1
  32. package/build/lib/index.d.ts +0 -1
  33. package/build/lib/index.d.ts.map +1 -1
  34. package/build/lib/index.js +0 -1
  35. package/build/lib/index.js.map +1 -1
  36. package/build/lib/init.d.ts +7 -131
  37. package/build/lib/init.d.ts.map +1 -1
  38. package/build/lib/init.js +2 -55
  39. package/build/lib/init.js.map +1 -1
  40. package/build/lib/model.d.ts +0 -11
  41. package/build/lib/model.d.ts.map +1 -1
  42. package/build/lib/validate.d.ts +2 -30
  43. package/build/lib/validate.d.ts.map +1 -1
  44. package/build/lib/validate.js +2 -93
  45. package/build/lib/validate.js.map +1 -1
  46. package/lib/builder/deploy.ts +17 -15
  47. package/lib/builder/index.ts +0 -2
  48. package/lib/builder/site.ts +6 -6
  49. package/lib/cli/command/build.ts +12 -59
  50. package/lib/cli/command/init.ts +0 -27
  51. package/lib/cli/command/validate.ts +3 -27
  52. package/lib/constants.ts +4 -17
  53. package/lib/fs.ts +16 -84
  54. package/lib/index.ts +0 -1
  55. package/lib/init.ts +9 -106
  56. package/lib/model.ts +0 -14
  57. package/lib/validate.ts +23 -172
  58. package/package.json +7 -13
  59. package/requirements.txt +4 -3
  60. package/tsconfig.json +1 -0
  61. package/build/lib/builder/nav.d.ts +0 -81
  62. package/build/lib/builder/nav.d.ts.map +0 -1
  63. package/build/lib/builder/nav.js +0 -288
  64. package/build/lib/builder/nav.js.map +0 -1
  65. package/build/lib/builder/reference.d.ts +0 -57
  66. package/build/lib/builder/reference.d.ts.map +0 -1
  67. package/build/lib/builder/reference.js +0 -111
  68. package/build/lib/builder/reference.js.map +0 -1
  69. package/build/lib/mike.d.ts +0 -81
  70. package/build/lib/mike.d.ts.map +0 -1
  71. package/build/lib/mike.js +0 -146
  72. package/build/lib/mike.js.map +0 -1
  73. package/lib/builder/nav.ts +0 -402
  74. package/lib/builder/reference.ts +0 -171
  75. package/lib/mike.js +0 -153
package/build/lib/mike.js DELETED
@@ -1,146 +0,0 @@
1
- "use strict";
2
- /**
3
- * API around `mike`, a tool for deploying multiple versions of MkDocs-built sites to GitHub Pages
4
- * @module
5
- */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.Mike = void 0;
11
- const teen_process_1 = require("teen_process");
12
- // eslint-disable-next-line import/no-unresolved
13
- const logger_1 = __importDefault(require("./logger"));
14
- const DEFAULT_REMOTE = 'origin';
15
- const DEFAULT_BRANCH = 'gh-pages';
16
- const MIKE_VER_STRING = 'mike 1.';
17
- /**
18
- * @deprecated Use the `deploy` export from `@appium/docutils`
19
- */
20
- class Mike {
21
- constructor(/** @type MikeOpts */ opts) {
22
- /** @type {boolean} */ this._mikeVerified = false;
23
- this.remote = opts.remote || DEFAULT_REMOTE;
24
- this.branch = opts.branch || DEFAULT_BRANCH;
25
- this.prefix = opts.prefix;
26
- this.configFile = opts.configFile;
27
- }
28
- /**
29
- * Throw an error if the 'mike' binary cannot be found
30
- *
31
- * @throws {Error}
32
- */
33
- async verifyMike() {
34
- if (this._mikeVerified) {
35
- return;
36
- }
37
- try {
38
- const { stdout } = await this.exec('--version', [], false);
39
- if (!stdout.includes(MIKE_VER_STRING)) {
40
- throw new Error('Mike was installed but was not version 1.x');
41
- }
42
- }
43
- catch (err) {
44
- throw new Error(`Could not verify appropriate mike binary exists: ${err}`);
45
- }
46
- this._mikeVerified = true;
47
- }
48
- /**
49
- * Get an array of args based on the class members that can be used with Mike-related subprocess
50
- * execution
51
- *
52
- * @param {string} cmdName - the name of the mike command to run
53
- * @param {string[]} cmdArgs - an array of command-specific arguments
54
- *
55
- * @returns {string[]}
56
- */
57
- getMikeArgs(cmdName, cmdArgs) {
58
- return [
59
- cmdName,
60
- ...cmdArgs,
61
- '--config-file',
62
- this.configFile,
63
- '--remote',
64
- this.remote,
65
- '--branch',
66
- this.branch,
67
- '--prefix',
68
- this.prefix,
69
- ];
70
- }
71
- /**
72
- * Exec mike as a subprocess
73
- *
74
- * @param {string} mikeCmd - the mike command to run
75
- * @param {string[]} [mikeArgs=[]] - the arguments to pass to the mike command
76
- * @param {boolean?} [verify=true] - whether to verify mike exists first
77
- *
78
- * @returns {Promise<import('teen_process').ExecResult<string>>}
79
- */
80
- async exec(mikeCmd, mikeArgs = [], verify = true) {
81
- if (verify) {
82
- await this.verifyMike();
83
- }
84
- const args = this.getMikeArgs(mikeCmd, mikeArgs);
85
- logger_1.default.debug(`Running mike ${args.join(' ')}`);
86
- return await (0, teen_process_1.exec)('mike', args);
87
- }
88
- /**
89
- * Return the list of mike deploys
90
- *
91
- * @returns {string[]}
92
- */
93
- async list() {
94
- const { stdout } = await this.exec('list');
95
- return stdout
96
- .split('\n')
97
- .map((s) => s.trim())
98
- .filter(Boolean);
99
- }
100
- /**
101
- * Set the default version or alias
102
- *
103
- * @param {string} alias - the version or alias
104
- */
105
- async setDefault(alias) {
106
- await this.exec('set-default', [alias]);
107
- }
108
- /**
109
- * Deploy docs to the branch
110
- *
111
- * @param {MikeDeployOpts} opts - the deploy options
112
- */
113
- async deploy(opts) {
114
- const args = [opts.version];
115
- if (opts.alias) {
116
- args.push(opts.alias, '--update-aliases');
117
- }
118
- if (opts.shouldPush) {
119
- args.push('--push');
120
- }
121
- if (opts.shouldRebase) {
122
- args.push('--rebase');
123
- }
124
- if (opts.commit) {
125
- args.push('--message', opts.commit);
126
- }
127
- await this.exec('deploy', args);
128
- }
129
- }
130
- exports.Mike = Mike;
131
- /**
132
- * @typedef MikeOpts - options for instantiating a Mike object
133
- * @property {string} [remote="origin"] - the git remote to push docs to
134
- * @property {string} [branch="gh-pages"] - the git branch to push docs to
135
- * @property {string?} prefix - the path prefix on the branch if any
136
- * @property {string} configFile - the mkdocs config file to use
137
- */
138
- /**
139
- * @typedef MikeDeployOpts - options for deploying docs with Mike
140
- * @param {string} version - the version to deploy
141
- * @param {string?} alias - the alias to alias (or re-alias) the version
142
- * @param {string?} commit - the commit message to use as an override
143
- * @param {boolean?} shouldPush - whether mike should push the commits to the remote
144
- * @param {boolean?} shouldRebase - whether mike should rebase
145
- */
146
- //# sourceMappingURL=mike.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mike.js","sourceRoot":"","sources":["../../lib/mike.js"],"names":[],"mappings":"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"}
@@ -1,402 +0,0 @@
1
- /**
2
- * Handles updating/adding the `nav` property of `mkdocs.yml`, based on the output of `typedoc`;
3
- * specifically, the command documentation generated by `@appium/typedoc-plugin-appium`.
4
- *
5
- * @module
6
- */
7
-
8
- import {fs} from '@appium/support';
9
- import _ from 'lodash';
10
- import path from 'node:path';
11
- import {
12
- DEFAULT_NAV_HEADER,
13
- DEFAULT_REL_TYPEDOC_OUT_PATH,
14
- NAME_BIN,
15
- NAME_MKDOCS_YML,
16
- NAME_TYPEDOC_JSON,
17
- } from '../constants';
18
- import {DocutilsError} from '../error';
19
- import {
20
- findDirsIn,
21
- findMkDocsYml,
22
- findTypeDocJsonPath,
23
- readTypedocJson,
24
- readYaml,
25
- safeWriteFile,
26
- stringifyYaml,
27
- } from '../fs';
28
- import {getLogger} from '../logger';
29
- import {MkDocsYml, MkDocsYmlNav} from '../model';
30
- import {relative} from '../util';
31
-
32
- const log = getLogger('builder:nav');
33
-
34
- /**
35
- * Gets a list of `.md` files relative to `docs_dir`
36
- * @param targetDir Directory ostensibly containing Markdown files; must be absolute
37
- * @param mkDocsDocsDir The path to the `docs_dir` in the `mkdocs.yml` file; must be absolute
38
- * @returns List of Markdown files relative to the `docs_dir` in the `mkdocs.yml` file
39
- */
40
- async function findRelativeMarkdownFiles(
41
- targetDir: string,
42
- mkDocsDocsDir: string
43
- ): Promise<string[]> {
44
- if (!path.isAbsolute(targetDir)) {
45
- throw new DocutilsError(`Expected absolute path, got '${targetDir}'`);
46
- }
47
- if (!path.isAbsolute(mkDocsDocsDir)) {
48
- throw new DocutilsError(`Expected absolute path, got '${mkDocsDocsDir}'`);
49
- }
50
- const relDir = path.relative(mkDocsDocsDir, targetDir);
51
- const dirEnts = await fs.readdir(targetDir, {withFileTypes: true});
52
- return dirEnts
53
- .filter((ent) => ent.isFile() && ent.name.endsWith('.md'))
54
- .map((ent) => path.join(relDir, ent.name));
55
- }
56
-
57
- /**
58
- * Because the `nav` property of `mkdocs.yml` is both a recursive type and a kind of awful one, it's
59
- * easier to work with it if we rewrite the data into a flat array of objects. We keep a `keypath`
60
- * prop which represents the deep/nested location within the `nav` object.
61
- *
62
- * @privateRemarks This function is not recursive; instead it loops over a queue of items to process
63
- * data, and we append to that queue while processing if needed.
64
- * @param nav Contents of the `nav` prop of `mkdocs.yml`
65
- * @returns A list of objects, each with a `keypath` property and a `fileOrUrl` property (and maybe
66
- * a `name` property)
67
- */
68
- export function parseNav(nav: MkDocsYmlNav): ParsedNavData[] {
69
- let parsedNav: ParsedNavData[] = [];
70
- const entries = Object.entries(nav);
71
- type QueueItem = {
72
- entries: typeof entries;
73
- keypath: string;
74
- };
75
- const queue: QueueItem[] = [{entries, keypath: ''}];
76
-
77
- while (queue.length) {
78
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
79
- const {entries, keypath} = queue.shift()!;
80
- for (const [key, item] of entries) {
81
- if (_.isString(item)) {
82
- const navData: ParsedNavData = {
83
- keypath: keypath ? `${keypath}.${key}` : key,
84
- fileOrUrl: item,
85
- };
86
-
87
- // if the key is not convertible to a number, it's a name
88
- // which was manually put there by somebody.
89
- if (Number.isNaN(Number(key))) {
90
- navData.name = key;
91
- }
92
- parsedNav = [...parsedNav, navData];
93
- } else if (_.isObject(item)) {
94
- const subEntries = Object.entries(item);
95
- queue.push({entries: subEntries, keypath: keypath ? `${keypath}.${key}` : key});
96
- }
97
- }
98
- }
99
- return parsedNav;
100
- }
101
-
102
- /**
103
- * Finds all items within the list of parsed nav data which correpsond to the header.
104
- *
105
- * This is imperfect, as it's possible for the header string to appear in multiple places in the
106
- * nav, but let's just ignore that until we can't.
107
- * @param navData Some parsed nav data
108
- * @param header Header name
109
- */
110
- function filterHeaderItems(navData: ParsedNavData[], header: string) {
111
- return _.filter(navData, (item) => _.toPath(item.keypath).includes(header));
112
- }
113
-
114
- /**
115
- * Given a root header keypath (like a prefix), a numeric offset, and some parsed nav data, compute
116
- * a keypath
117
- *
118
- * @param rootHeaderKeypath Root keypath as determined by {@linkcode getRootHeaderKeypath}
119
- * @param offset Numeric offset within the array of items for the header
120
- * @param data Any parsed nav data found. For new items, this will be `undefined`. If not new, it
121
- * may or may not have a `name` prop, and if it does, we want to retain it.
122
- * @returns Complete keypath for a nav item beginning with the root keypath
123
- */
124
- function getKeypathForHeaderItem(rootHeaderKeypath: string, offset: number, data?: ParsedNavData) {
125
- return data?.name
126
- ? `${rootHeaderKeypath}.${offset}.${data.name}`
127
- : `${rootHeaderKeypath}.${offset}`;
128
- }
129
-
130
- /**
131
- * Compares two sets of nav data and determines if they are different.
132
- *
133
- * This does not compare the entire `nav` object with a new one; it works per-header
134
- * @param newNavData Nav data as computed by {@linkcode getNavItemsForDir} corresponding to a
135
- * particular header
136
- * @param navData Subset of original nav data as parsed by {@linkcode parseNav}, corresponding to
137
- * the same header
138
- */
139
- function navDataDidChange(
140
- newNavData: Array<Omit<ParsedNavData, 'name'>>,
141
- navData: ParsedNavData[]
142
- ): boolean {
143
- // the result should be the items from newNavData which either don't appear in
144
- // navdata, or the items which do appear in navData but have a different fileOrUrl
145
- const matchedKeypaths = _.intersectionBy(newNavData, navData, 'keypath');
146
- const diff = _.xorBy(newNavData, matchedKeypaths, 'fileOrUrl');
147
- return !_.isEmpty(diff);
148
- }
149
-
150
- /**
151
- * Find the "root" keypath for a particular header
152
- *
153
- * @param headerItems Some subset of the nav data having keypaths corresponding to `header`
154
- * @param header Header string
155
- * @returns The keypath up to the header string, inclusive
156
- */
157
- function getRootHeaderKeypath(headerItems: ParsedNavData[], header: string) {
158
- // these are the parts of the keypath of the first item, which will contain the header string. it
159
- // dosn't matter whether we pick the first one or any one; they will all contain the same root
160
- // keypath by definition.
161
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
162
- const rootHeaderKeypathParts = _.toPath(_.first(headerItems)!.keypath);
163
-
164
- // this is the keypath up to the header string, inclusive.
165
- // we append indices or names to this keypath
166
- return rootHeaderKeypathParts.slice(0, rootHeaderKeypathParts.indexOf(header) + 1).join('.');
167
- }
168
-
169
- /**
170
- * This examines the `navData` looking for items matching the header string (which _may_ be defined
171
- * by `dir`; if `all` is true, we just use the default header, because we will be returning a whole
172
- * lot of headers).
173
- *
174
- * @param dir Abs path to directory containing markdown files generated by TypeDoc
175
- * @param mkDocsDocsDir Configured `docs_dir` or via options
176
- * @param navData Nav data parsed by {@linkcode parseNav}
177
- * @param all If `true`, process all markdown files, not just commands
178
- */
179
- async function getNavItemsForDir(
180
- dir: string,
181
- mkDocsDocsDir: string,
182
- navData: ParsedNavData[],
183
- nav: MkDocsYmlNav,
184
- all = false
185
- ) {
186
- let dataChanged = false;
187
- const newNavHeaderItems: Omit<ParsedNavData, 'name'>[] = [];
188
- const referenceOutputFilepaths = await findRelativeMarkdownFiles(dir, mkDocsDocsDir);
189
- if (!referenceOutputFilepaths.length) {
190
- log.warn('No markdown files found in %s; did TypeDoc run?', dir);
191
- return {data: [], changed: false};
192
- }
193
-
194
- const navHeader = all ? _.startCase(path.basename(dir)) : DEFAULT_NAV_HEADER;
195
- const navHeaderItems = filterHeaderItems(navData, navHeader);
196
-
197
- // if we found items with this header already, we are going
198
- // to replace them all wholesale
199
- if (navHeaderItems.length) {
200
- log.debug('Found %d item(s) in header %s', navHeaderItems.length, navHeader);
201
- // we append indices or names to this keypath
202
- const rootHeaderKeypath = getRootHeaderKeypath(navHeaderItems, navHeader);
203
-
204
- for (const fileOrUrl of referenceOutputFilepaths) {
205
- const offset = navHeaderItems.findIndex((item) => item.fileOrUrl === fileOrUrl);
206
- const newOffset = offset >= 0 ? offset : navHeaderItems.length;
207
- const data = navHeaderItems[offset];
208
- const keypath = getKeypathForHeaderItem(rootHeaderKeypath, newOffset, data);
209
- newNavHeaderItems.push({keypath, fileOrUrl});
210
- }
211
-
212
- // look for any differences between what we have and what's in the file
213
- if (navDataDidChange(newNavHeaderItems, navHeaderItems)) {
214
- log.debug('Will write new nav data for header %s: %O', navHeader, newNavHeaderItems);
215
- dataChanged = true;
216
- } else {
217
- log.debug('No changes for header %s', navHeader);
218
- }
219
- } else {
220
- log.debug('No items found in header %s', navHeader);
221
- const navOffset = nav.length;
222
- for (const [idx, newRefFilepath] of referenceOutputFilepaths.entries()) {
223
- newNavHeaderItems.push({
224
- keypath: `${navOffset}.${navHeader}.${idx}`,
225
- fileOrUrl: newRefFilepath,
226
- });
227
- }
228
- log.debug('Will create nav data for header %s', navHeader);
229
- dataChanged = true;
230
- }
231
- return {data: newNavHeaderItems, changed: dataChanged};
232
- }
233
-
234
- /**
235
- * Applies the changes in `newData` to the `mkDocsYml` object.
236
- *
237
- * **This function mutates `mkDocsYml`.**
238
- * @param newData New nav data
239
- * @param mkDocsYml Original `mkdocs.yml`
240
- */
241
- function applyNavData(newData: ParsedNavData[], mkDocsYml: MkDocsYml) {
242
- for (const {keypath, fileOrUrl} of newData) {
243
- _.set(mkDocsYml, `nav.${keypath}`, fileOrUrl);
244
- }
245
- }
246
-
247
- /**
248
- * Update the `nav` property of `mkdocs.yml` with a list of "command" files generated by TypeDoc via
249
- * `@appium/typedoc-plugin-appium`.
250
- *
251
- * To be clear, this function **modifies the MkDocs config file (`mkdocs.yml`) in place**; it is
252
- * typically under version control, so if this function makes any changes, you'll want to commit them.
253
- * @param opts - Options
254
- * @todo implement `dryRun` option
255
- */
256
- export async function updateNav({
257
- cwd = process.cwd(),
258
- mkdocsYml: mkDocsYmlPath,
259
- typedocJson: typeDocJsonPath,
260
- all = false,
261
- }: UpdateNavOpts = {}) {
262
- // we need `mkdocs.yml` to update
263
- // and we need `typedoc.json` to know where to look for the command docs
264
- [mkDocsYmlPath, typeDocJsonPath] = await Promise.all([
265
- mkDocsYmlPath ?? findMkDocsYml(cwd),
266
- typeDocJsonPath ?? findTypeDocJsonPath(cwd),
267
- ]);
268
- if (!mkDocsYmlPath) {
269
- throw new DocutilsError(
270
- `Could not find ${NAME_MKDOCS_YML} from ${cwd}; run "${NAME_BIN} init" to create it`
271
- );
272
- }
273
- if (!typeDocJsonPath) {
274
- throw new DocutilsError(
275
- `Could not find ${NAME_TYPEDOC_JSON} from ${cwd}; run "${NAME_BIN} init" to create it`
276
- );
277
- }
278
- const relativePath = relative(cwd);
279
- const relMkDocsYmlPath = relativePath(mkDocsYmlPath);
280
- const typeDocJson = readTypedocJson(typeDocJsonPath);
281
- const mkDocsYml = (await readYaml(mkDocsYmlPath)) as MkDocsYml;
282
-
283
- /**
284
- * Absolute path to `typedoc.json`
285
- */
286
- const absTypeDocJsonPath = path.isAbsolute(typeDocJsonPath)
287
- ? typeDocJsonPath
288
- : path.resolve(cwd, typeDocJsonPath);
289
-
290
- /**
291
- * Absolute path to TypeDoc's output directory (`out`)
292
- */
293
- const typeDocOutDir = path.resolve(
294
- path.dirname(absTypeDocJsonPath),
295
- typeDocJson.out ? typeDocJson.out : DEFAULT_REL_TYPEDOC_OUT_PATH
296
- );
297
-
298
- /**
299
- * Absolute path to `mkdocs.yml`
300
- */
301
- const absMkdocsYmlPath = path.isAbsolute(mkDocsYmlPath)
302
- ? mkDocsYmlPath
303
- : path.resolve(cwd, mkDocsYmlPath);
304
-
305
- const {docs_dir: docsDir, nav = []} = mkDocsYml;
306
- /**
307
- * Absolute path to the directory containing MkDocs input docs
308
- */
309
- const mkDocsDocsDir = path.resolve(path.dirname(absMkdocsYmlPath), docsDir ?? 'docs');
310
-
311
- /**
312
- * @todo
313
- * `commands` is a dirname configurable via the `commandsDir` option added by
314
- * `@appium/typedoc-plugin-appium`. this lives in `typedoc.json`, but in order for it to be parsed
315
- * using TypeDoc's facilities, we have to load plugins before reading `typedoc.json`, which is
316
- * slow. we will probably have to support this in the future, but for now, we can just hardcode it
317
- */
318
- const dirs = all ? await findDirsIn(typeDocOutDir) : [path.join(typeDocOutDir, 'commands')];
319
-
320
- let shouldWriteMkDocsYml = false;
321
-
322
- const navData = parseNav(nav);
323
-
324
- // this is the thing which will be assigned to the `nav` prop
325
- // and thus written to `mkdocs.yml` if there were any changes.
326
- // we don't need the `name` prop, since the name is already present in the keypath.
327
- const newData: Omit<ParsedNavData, 'name'>[] = [];
328
-
329
- for await (const dir of dirs) {
330
- const {data, changed} = await getNavItemsForDir(dir, mkDocsDocsDir, navData, nav, all);
331
- if (changed) {
332
- shouldWriteMkDocsYml = true;
333
- }
334
- newData.push(...data);
335
- }
336
-
337
- if (shouldWriteMkDocsYml) {
338
- applyNavData(newData, mkDocsYml);
339
- const yaml = stringifyYaml(mkDocsYml);
340
- log.debug('Writing to %s:\n%s', mkDocsYmlPath, yaml);
341
- await safeWriteFile(mkDocsYmlPath, yaml, true);
342
- log.success(
343
- 'Updated MkDocs navigation config for reference docs; please run "git add -A %s" and commit this change',
344
- relMkDocsYmlPath
345
- );
346
- } else {
347
- log.info('No changes needed for MkDocs config at %s', relMkDocsYmlPath);
348
- }
349
- }
350
-
351
- /**
352
- * Options for {@linkcode updateNav}
353
- */
354
- export interface UpdateNavOpts {
355
- /**
356
- * Current working directory
357
- */
358
- cwd?: string;
359
- /**
360
- * Path to `mkdocs.yml`
361
- */
362
- mkdocsYml?: string;
363
- /**
364
- * Path to `package.json`
365
- */
366
- packageJson?: string;
367
- /**
368
- * Path to `typedoc.json`
369
- */
370
- typedocJson?: string;
371
- /**
372
- * If `true`, do not write any files
373
- * @remarks Not yet implemented
374
- */
375
- dryRun?: boolean;
376
-
377
- /**
378
- * If `true`, add _all_ reference documentation to the navigation config (not just commands)
379
- */
380
- all?: boolean;
381
- }
382
-
383
- /**
384
- * Used internally by {@linkcode updatedNav}
385
- * @see {@linkcode parseNav}
386
- */
387
- interface ParsedNavData {
388
- /**
389
- * Keypath within `nav` for some file or URL
390
- */
391
- keypath: string;
392
- /**
393
- * A filepath (usually) or a URL.
394
- * This is considered the "index" of the data, and should be unique within its parent. If it's not
395
- * unique, then it will probably end up that way after updating...
396
- */
397
- fileOrUrl: string;
398
- /**
399
- * If this file or url has a proper name, this would be it. Most don't.
400
- */
401
- name?: string;
402
- }