Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom extension mapping #14

Merged
merged 4 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/cjs/actions/check.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const consts_1 = require("./consts");
* Compare the digest of the best practices against the stored digest to
* see if the docs need to be updated.
*/
const checkAction = ({ srcPath, generatedPath }) => __awaiter(void 0, void 0, void 0, function* () {
const checkAction = (_a) => __awaiter(void 0, [_a], void 0, function* ({ srcPath, generatedPath }) {
const bestPractices = yield (0, parse_1.getAllBestPractices)(srcPath);
const currentDigest = (0, digest_1.getBestPracticesDigest)(bestPractices);
const previousDigest = yield getPreviousBestPracticesDigest(generatedPath);
Expand Down
33 changes: 18 additions & 15 deletions lib/cjs/actions/write.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getBestPracticeFileLines = exports.SPECIAL_META_KEYS = exports.writeBestPractices = void 0;
exports.SPECIAL_META_KEYS = exports.writeBestPractices = void 0;
exports.default = writeAction;
exports.getBestPracticeFileLines = getBestPracticeFileLines;
const promises_1 = require("fs/promises");
const path_1 = __importDefault(require("path"));
const codeType_1 = require("../utils/codeType");
const digest_1 = require("../utils/digest");
const fs_1 = require("../utils/fs");
const parse_1 = require("../utils/parse");
Expand All @@ -24,31 +27,31 @@ const consts_1 = require("./consts");
/**
* Generate best practices from source and write them out.
*/
function writeAction({ srcPath, docsPath, generatedPath, codeUrl, options, }) {
return __awaiter(this, void 0, void 0, function* () {
function writeAction(_a) {
return __awaiter(this, arguments, void 0, function* ({ srcPath, docsPath, generatedPath, codeUrl, extensionMappings, options, }) {
const codeTypeMap = (0, codeType_1.buildCodeTypeMap)(extensionMappings !== null && extensionMappings !== void 0 ? extensionMappings : []);
const allBestPractices = yield (0, parse_1.getAllBestPractices)(srcPath);
let filteredBestPractices;
if (docsPath) {
// It's OK if the generatedPath is within docsPath, because we'll completely replace
// the generated path next. This is a feature not a bug.
const usedIds = yield (0, replace_1.replaceAllBestPracticesInDocs)(docsPath, allBestPractices, (bestPractice) => getBestPracticeCodeLines(bestPractice, codeUrl));
const usedIds = yield (0, replace_1.replaceAllBestPracticesInDocs)(docsPath, allBestPractices, (bestPractice) => getBestPracticeCodeLines(bestPractice, codeUrl, codeTypeMap));
// If a best practice was written out to a static file, do not also include it in the
// generated output
filteredBestPractices = allBestPractices.filter((bp) => !usedIds.has(bp.getMeta('id')));
}
else {
filteredBestPractices = allBestPractices;
}
yield (0, exports.writeBestPractices)(generatedPath, filteredBestPractices, codeUrl, options);
yield (0, exports.writeBestPractices)(generatedPath, filteredBestPractices, codeUrl, codeTypeMap, options);
yield writeBestPracticesDigest(generatedPath, (0, digest_1.getBestPracticesDigest)(allBestPractices));
return filteredBestPractices;
});
}
exports.default = writeAction;
/**
* Writes best practices out to Markdown doc files.
*/
const writeBestPractices = (contentDir, bestPractices, codeUrl, options) => __awaiter(void 0, void 0, void 0, function* () {
const writeBestPractices = (contentDir, bestPractices, codeUrl, codeTypeMap, options) => __awaiter(void 0, void 0, void 0, function* () {
try {
yield (0, promises_1.rm)(contentDir, { recursive: true });
}
Expand All @@ -57,15 +60,15 @@ const writeBestPractices = (contentDir, bestPractices, codeUrl, options) => __aw
}
yield (0, promises_1.mkdir)(contentDir);
for (const bestPractice of bestPractices) {
yield writeBestPracticeToFile(contentDir, bestPractice, codeUrl, options);
yield writeBestPracticeToFile(contentDir, bestPractice, codeUrl, codeTypeMap, options);
}
});
exports.writeBestPractices = writeBestPractices;
exports.SPECIAL_META_KEYS = new Set(['title', 'subtitle', 'description']);
/**
* Write a best practice to a markdown file.
*/
const writeBestPracticeToFile = (dir, bestPractice, codeUrl, options) => __awaiter(void 0, void 0, void 0, function* () {
const writeBestPracticeToFile = (dir, bestPractice, codeUrl, codeTypeMap, options) => __awaiter(void 0, void 0, void 0, function* () {
const { filepath, filename } = bestPractice.getFileInfo();
const dirpath = path_1.default.join(dir, ...filepath);
const fullpath = path_1.default.join(dirpath, filename);
Expand All @@ -78,7 +81,7 @@ const writeBestPracticeToFile = (dir, bestPractice, codeUrl, options) => __await
yield (0, promises_1.mkdir)(dirpath, { recursive: true });
}
fd = yield (0, promises_1.open)(fullpath, 'a');
for (const line of getBestPracticeFileLines(bestPractice, codeUrl, Object.assign({ writeTitle }, options))) {
for (const line of getBestPracticeFileLines(bestPractice, codeUrl, codeTypeMap, Object.assign({ writeTitle }, options))) {
yield (0, fs_1.writeLine)(fd, line);
}
}
Expand All @@ -89,7 +92,7 @@ const writeBestPracticeToFile = (dir, bestPractice, codeUrl, options) => __await
/**
* Generate best practice lines.
*/
function* getBestPracticeFileLines(bestPractice, codeUrl, { writeTitle = true, writeExtraMeta = false }) {
function* getBestPracticeFileLines(bestPractice, codeUrl, codeTypeMap, { writeTitle = true, writeExtraMeta = false }) {
if (writeTitle) {
yield '---';
yield `title: ${bestPractice.getTitle()}`;
Expand Down Expand Up @@ -118,16 +121,16 @@ function* getBestPracticeFileLines(bestPractice, codeUrl, { writeTitle = true, w
}
yield '';
}
for (const line of getBestPracticeCodeLines(bestPractice, codeUrl)) {
for (const line of getBestPracticeCodeLines(bestPractice, codeUrl, codeTypeMap)) {
yield line;
}
}
exports.getBestPracticeFileLines = getBestPracticeFileLines;
const getBestPracticeCodeLines = (bestPractice, codeUrl) => {
const getBestPracticeCodeLines = (bestPractice, codeUrl, codeTypeMap) => {
const { sourceFilename, startLine, endLine } = bestPractice;
const url = `${codeUrl}/${sourceFilename}#L${startLine}-L${endLine}`;
const codeType = codeTypeMap(bestPractice.getFileType());
return [
`\`\`\`${bestPractice.getFileType()}`,
`\`\`\`${codeType}`,
...(0, string_1.unindent)(bestPractice.codeLines),
'```',
`From [${sourceFilename} lines ${startLine}-${endLine}](${url})`,
Expand Down
1 change: 1 addition & 0 deletions lib/cjs/best-practices.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const main = () => {
.option('-d, --docs-path <docsPath>')
.requiredOption('-g, --generated-path <generatedPath>')
.requiredOption('-u, --code-url <codeUrl>')
.option('-m, --extension-mappings <mappings...>', 'e.g. jsx:js to map jsx to js')
.action((args) => {
(0, write_1.default)(Object.assign(Object.assign({}, args), { options: {} }));
});
Expand Down
24 changes: 17 additions & 7 deletions lib/cjs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Expand Down
8 changes: 5 additions & 3 deletions lib/cjs/types/actions/write.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import BestPractice from '../BestPractice';
import { type CodeTypeMapper } from '../utils/codeType';
type WriteOptions = {
writeExtraMeta?: boolean;
};
Expand All @@ -7,16 +8,17 @@ type WriteArgs = {
docsPath?: string;
generatedPath: string;
codeUrl: string;
extensionMappings?: string[];
options: WriteOptions;
};
/**
* Generate best practices from source and write them out.
*/
export default function writeAction({ srcPath, docsPath, generatedPath, codeUrl, options, }: WriteArgs): Promise<BestPractice[]>;
export default function writeAction({ srcPath, docsPath, generatedPath, codeUrl, extensionMappings, options, }: WriteArgs): Promise<BestPractice[]>;
/**
* Writes best practices out to Markdown doc files.
*/
export declare const writeBestPractices: (contentDir: string, bestPractices: BestPractice[], codeUrl: string, options: WriteOptions) => Promise<void>;
export declare const writeBestPractices: (contentDir: string, bestPractices: BestPractice[], codeUrl: string, codeTypeMap: CodeTypeMapper, options: WriteOptions) => Promise<void>;
export declare const SPECIAL_META_KEYS: Set<string>;
type WriteBestPracticeOptions = {
writeTitle?: boolean;
Expand All @@ -25,6 +27,6 @@ type WriteBestPracticeOptions = {
/**
* Generate best practice lines.
*/
export declare function getBestPracticeFileLines(bestPractice: BestPractice, codeUrl: string, { writeTitle, writeExtraMeta }: WriteBestPracticeOptions): Generator<string>;
export declare function getBestPracticeFileLines(bestPractice: BestPractice, codeUrl: string, codeTypeMap: CodeTypeMapper, { writeTitle, writeExtraMeta }: WriteBestPracticeOptions): Generator<string>;
export {};
//# sourceMappingURL=write.d.ts.map
2 changes: 1 addition & 1 deletion lib/cjs/types/actions/write.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions lib/cjs/types/utils/codeType.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export type CodeTypeMapper = (ext: string) => string;
/**
* Convert a list of mappings to a function to map file extension to code type.
*
* E.g. if you want files with a .tsx extension to have a ts code type for examples you could
*
* buildCodeTypeMap(['tsx:ts', 'jsx:js'])
*/
export declare const buildCodeTypeMap: (mappings?: string[]) => CodeTypeMapper;
//# sourceMappingURL=codeType.d.ts.map
1 change: 1 addition & 0 deletions lib/cjs/types/utils/codeType.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion lib/cjs/types/utils/fs.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/// <reference types="node" />
import { type FileHandle } from 'fs/promises';
/**
* Asynchronously walks through a directory structure and yields filenames.
Expand Down
2 changes: 1 addition & 1 deletion lib/cjs/types/utils/fs.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/cjs/types/utils/replace.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions lib/cjs/utils/codeType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildCodeTypeMap = void 0;
/**
* Convert a list of mappings to a function to map file extension to code type.
*
* E.g. if you want files with a .tsx extension to have a ts code type for examples you could
*
* buildCodeTypeMap(['tsx:ts', 'jsx:js'])
*/
const buildCodeTypeMap = (mappings = []) => {
const map = Object.fromEntries(mappings.map((value) => value.split(':')));
return (ext) => map[ext] || ext;
};
exports.buildCodeTypeMap = buildCodeTypeMap;
10 changes: 5 additions & 5 deletions lib/cjs/utils/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
Expand All @@ -34,7 +34,8 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isDocFile = exports.isCodeFile = exports.writeFileLines = exports.readFileLines = exports.pathExists = exports.writeLine = exports.walk = void 0;
exports.isDocFile = exports.isCodeFile = exports.writeFileLines = exports.readFileLines = exports.pathExists = exports.writeLine = void 0;
exports.walk = walk;
const fs_1 = require("fs");
const promises_1 = require("fs/promises");
const promises_2 = require("fs/promises");
Expand All @@ -43,8 +44,8 @@ const path_1 = require("path");
* Asynchronously walks through a directory structure and yields filenames.
* Uses a depth-first search pattern.
*/
function walk(dir, context = '') {
return __asyncGenerator(this, arguments, function* walk_1() {
function walk(dir_1) {
return __asyncGenerator(this, arguments, function* walk_1(dir, context = '') {
const entries = yield __await((0, promises_2.readdir)(dir, { withFileTypes: true }));
for (const entry of entries) {
if (entry.isDirectory()) {
Expand All @@ -57,7 +58,6 @@ function walk(dir, context = '') {
}
});
}
exports.walk = walk;
/**
* Writes text to a file descriptor, adding a trailing newline.
*/
Expand Down
Loading
Loading