@codedrifters/configulator 0.0.269 → 0.0.271

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/lib/index.js CHANGED
@@ -270,6 +270,7 @@ __export(index_exports, {
270
270
  STARLIGHT_ROLE: () => STARLIGHT_ROLE,
271
271
  StarlightProject: () => StarlightProject,
272
272
  TestRunner: () => TestRunner,
273
+ TsDocCoverageKind: () => TsDocCoverageKind,
273
274
  TurboRepo: () => TurboRepo,
274
275
  TurboRepoTask: () => TurboRepoTask,
275
276
  TypeScriptConfig: () => TypeScriptConfig,
@@ -284,6 +285,7 @@ __export(index_exports, {
284
285
  addBuildCompleteJob: () => addBuildCompleteJob,
285
286
  addSyncLabelsWorkflow: () => addSyncLabelsWorkflow,
286
287
  agendaBundle: () => agendaBundle,
288
+ analyzeTsDocCoverage: () => analyzeTsDocCoverage,
287
289
  awsCdkBundle: () => awsCdkBundle,
288
290
  baseBundle: () => baseBundle,
289
291
  bcmWriterBundle: () => bcmWriterBundle,
@@ -314,6 +316,7 @@ __export(index_exports, {
314
316
  customerProfileBundle: () => customerProfileBundle,
315
317
  docsSyncBundle: () => docsSyncBundle,
316
318
  extractApiProcedure: () => extractApiProcedure,
319
+ extractDocReferences: () => extractDocReferences,
317
320
  formatLayoutViolation: () => formatLayoutViolation,
318
321
  formatStarlightSingletonViolation: () => formatStarlightSingletonViolation,
319
322
  getLatestEligibleVersion: () => getLatestEligibleVersion,
@@ -26768,8 +26771,8 @@ var FALLBACKS = {
26768
26771
  monorepoLayoutSeedBlock: ""
26769
26772
  };
26770
26773
  var TEMPLATE_RE = /\{\{(\w+(?:\.\w+)*)\}\}/g;
26771
- function getNestedValue(obj, path2) {
26772
- const parts = path2.split(".");
26774
+ function getNestedValue(obj, path4) {
26775
+ const parts = path4.split(".");
26773
26776
  let current = obj;
26774
26777
  for (const part of parts) {
26775
26778
  if (current == null || typeof current !== "object") {
@@ -26995,20 +26998,20 @@ var ClaudeRenderer = class _ClaudeRenderer {
26995
26998
  obj.excludedCommands = [...sandbox.excludedCommands];
26996
26999
  }
26997
27000
  if (sandbox.filesystem) {
26998
- const fs = {};
27001
+ const fs2 = {};
26999
27002
  if (sandbox.filesystem.allowRead?.length) {
27000
- fs.allowRead = [...sandbox.filesystem.allowRead];
27003
+ fs2.allowRead = [...sandbox.filesystem.allowRead];
27001
27004
  }
27002
27005
  if (sandbox.filesystem.denyRead?.length) {
27003
- fs.denyRead = [...sandbox.filesystem.denyRead];
27006
+ fs2.denyRead = [...sandbox.filesystem.denyRead];
27004
27007
  }
27005
27008
  if (sandbox.filesystem.allowWrite?.length) {
27006
- fs.allowWrite = [...sandbox.filesystem.allowWrite];
27009
+ fs2.allowWrite = [...sandbox.filesystem.allowWrite];
27007
27010
  }
27008
27011
  if (sandbox.filesystem.denyWrite?.length) {
27009
- fs.denyWrite = [...sandbox.filesystem.denyWrite];
27012
+ fs2.denyWrite = [...sandbox.filesystem.denyWrite];
27010
27013
  }
27011
- if (Object.keys(fs).length > 0) obj.filesystem = fs;
27014
+ if (Object.keys(fs2).length > 0) obj.filesystem = fs2;
27012
27015
  }
27013
27016
  if (sandbox.network) {
27014
27017
  const net = {};
@@ -28753,6 +28756,343 @@ var AwsDeploymentTarget = class _AwsDeploymentTarget extends import_projen12.Com
28753
28756
  }
28754
28757
  };
28755
28758
 
28759
+ // src/docs-sync/reference-extraction/extraction.ts
28760
+ var fs = __toESM(require("fs"));
28761
+ var path2 = __toESM(require("path"));
28762
+ var import_mdast_util_from_markdown = require("mdast-util-from-markdown");
28763
+ var DEFAULT_DOCS_ROOT = "docs/src/content/docs";
28764
+ var DEFAULT_SYMBOL_PATTERN = /^(?:[a-z][a-zA-Z0-9]*|[A-Z][a-zA-Z0-9]*|[A-Z][A-Z0-9_]*)$/;
28765
+ function extractDocReferences(options = {}) {
28766
+ const docsRoot = path2.resolve(options.docsRoot ?? DEFAULT_DOCS_ROOT);
28767
+ const symbolPattern = options.symbolPattern ?? DEFAULT_SYMBOL_PATTERN;
28768
+ const knownSymbols = new Set(options.knownSymbols ?? []);
28769
+ if (!fs.existsSync(docsRoot)) {
28770
+ return [];
28771
+ }
28772
+ const records = [];
28773
+ for (const absolutePath of walkMarkdownFiles(docsRoot)) {
28774
+ const docPath = toPosix(path2.relative(docsRoot, absolutePath));
28775
+ const source = fs.readFileSync(absolutePath, "utf-8");
28776
+ const tree = (0, import_mdast_util_from_markdown.fromMarkdown)(stripYamlFrontmatter(source));
28777
+ collectInlineCode(tree, (symbol, position) => {
28778
+ if (!symbolPattern.test(symbol)) {
28779
+ return;
28780
+ }
28781
+ records.push({
28782
+ docPath,
28783
+ line: position.line,
28784
+ column: position.column,
28785
+ symbol,
28786
+ isKnown: knownSymbols.has(symbol)
28787
+ });
28788
+ });
28789
+ }
28790
+ records.sort((a, b) => {
28791
+ if (a.docPath !== b.docPath) {
28792
+ return a.docPath.localeCompare(b.docPath);
28793
+ }
28794
+ if (a.line !== b.line) {
28795
+ return a.line - b.line;
28796
+ }
28797
+ if (a.column !== b.column) {
28798
+ return a.column - b.column;
28799
+ }
28800
+ return a.symbol.localeCompare(b.symbol);
28801
+ });
28802
+ return records;
28803
+ }
28804
+ function walkMarkdownFiles(root) {
28805
+ const out = [];
28806
+ const stack = [root];
28807
+ while (stack.length > 0) {
28808
+ const dir = stack.pop();
28809
+ let entries;
28810
+ try {
28811
+ entries = fs.readdirSync(dir, { withFileTypes: true });
28812
+ } catch {
28813
+ continue;
28814
+ }
28815
+ for (const entry of entries) {
28816
+ const full = path2.join(dir, entry.name);
28817
+ if (entry.isDirectory()) {
28818
+ stack.push(full);
28819
+ } else if (entry.isFile() && full.toLowerCase().endsWith(".md")) {
28820
+ out.push(full);
28821
+ }
28822
+ }
28823
+ }
28824
+ out.sort();
28825
+ return out;
28826
+ }
28827
+ function collectInlineCode(tree, visit) {
28828
+ walk(tree);
28829
+ function walk(node) {
28830
+ if (node.type === "inlineCode") {
28831
+ const start = node.position?.start;
28832
+ if (!start) {
28833
+ return;
28834
+ }
28835
+ visit(node.value, { line: start.line, column: start.column });
28836
+ return;
28837
+ }
28838
+ if (node.type === "code" || node.type === "html") {
28839
+ return;
28840
+ }
28841
+ const parent = node;
28842
+ if (Array.isArray(parent.children)) {
28843
+ for (const child of parent.children) {
28844
+ walk(child);
28845
+ }
28846
+ }
28847
+ }
28848
+ }
28849
+ function toPosix(p) {
28850
+ return p.split(path2.sep).join("/");
28851
+ }
28852
+ function stripYamlFrontmatter(source) {
28853
+ if (!source.startsWith("---")) {
28854
+ return source;
28855
+ }
28856
+ const lines = source.split("\n");
28857
+ if (lines[0] !== "---") {
28858
+ return source;
28859
+ }
28860
+ let endIndex = -1;
28861
+ for (let i = 1; i < lines.length; i++) {
28862
+ if (lines[i] === "---") {
28863
+ endIndex = i;
28864
+ break;
28865
+ }
28866
+ }
28867
+ if (endIndex < 0) {
28868
+ return source;
28869
+ }
28870
+ for (let i = 0; i <= endIndex; i++) {
28871
+ lines[i] = "";
28872
+ }
28873
+ return lines.join("\n");
28874
+ }
28875
+
28876
+ // src/docs-sync/tsdoc-coverage/coverage.ts
28877
+ var path3 = __toESM(require("path"));
28878
+ var import_tsdoc = require("@microsoft/tsdoc");
28879
+ var ts = __toESM(require("typescript"));
28880
+ var TsDocCoverageKind = {
28881
+ Class: "Class",
28882
+ Interface: "Interface",
28883
+ TypeAlias: "TypeAlias",
28884
+ Enum: "Enum",
28885
+ Function: "Function",
28886
+ Variable: "Variable",
28887
+ Module: "Module",
28888
+ Default: "Default",
28889
+ Other: "Other"
28890
+ };
28891
+ var DEFAULT_THIN_SUMMARY_WORD_THRESHOLD = 4;
28892
+ var DEFAULT_ENTRY_POINT = "src/index.ts";
28893
+ function analyzeTsDocCoverage(options) {
28894
+ const resolvedOptions = typeof options === "string" ? { packageRoot: options } : options;
28895
+ const packageRoot = path3.resolve(resolvedOptions.packageRoot);
28896
+ const entryPoint = path3.resolve(
28897
+ packageRoot,
28898
+ resolvedOptions.entryPoint ?? DEFAULT_ENTRY_POINT
28899
+ );
28900
+ const thinThreshold = resolvedOptions.thinSummaryWordThreshold ?? DEFAULT_THIN_SUMMARY_WORD_THRESHOLD;
28901
+ const compilerOptions = resolveCompilerOptions(
28902
+ packageRoot,
28903
+ resolvedOptions.tsconfigPath
28904
+ );
28905
+ const program = ts.createProgram({
28906
+ rootNames: [entryPoint],
28907
+ options: compilerOptions
28908
+ });
28909
+ const checker = program.getTypeChecker();
28910
+ const entrySource = program.getSourceFile(entryPoint);
28911
+ if (!entrySource) {
28912
+ throw new Error(
28913
+ `analyzeTsDocCoverage: entry point not found in program: ${entryPoint}`
28914
+ );
28915
+ }
28916
+ const moduleSymbol = checker.getSymbolAtLocation(entrySource);
28917
+ if (!moduleSymbol) {
28918
+ return [];
28919
+ }
28920
+ const tsdocParser = new import_tsdoc.TSDocParser();
28921
+ const records = [];
28922
+ for (const exportSymbol of checker.getExportsOfModule(moduleSymbol)) {
28923
+ const resolved = resolveAlias(exportSymbol, checker);
28924
+ const declaration = pickPrimaryDeclaration(resolved);
28925
+ if (!declaration) {
28926
+ continue;
28927
+ }
28928
+ const kind = classifyDeclaration(declaration);
28929
+ const location = resolveLocation(declaration);
28930
+ const tsdoc = parseTsDocFor(declaration, tsdocParser);
28931
+ const summaryWordCount = tsdoc ? countSummaryWords(tsdoc) : 0;
28932
+ const hasSummary = summaryWordCount > 0;
28933
+ const hasThinSummary = hasSummary && summaryWordCount <= thinThreshold;
28934
+ const hasParams = tsdoc ? hasBlockTag(tsdoc, "@param") : false;
28935
+ const hasReturns = tsdoc ? hasBlockTag(tsdoc, "@returns") || hasBlockTag(tsdoc, "@return") : false;
28936
+ records.push({
28937
+ symbol: exportSymbol.getName(),
28938
+ kind,
28939
+ location,
28940
+ hasSummary,
28941
+ hasThinSummary,
28942
+ hasParams,
28943
+ hasReturns
28944
+ });
28945
+ }
28946
+ records.sort((a, b) => {
28947
+ if (a.location.file !== b.location.file) {
28948
+ return a.location.file.localeCompare(b.location.file);
28949
+ }
28950
+ if (a.location.line !== b.location.line) {
28951
+ return a.location.line - b.location.line;
28952
+ }
28953
+ return a.symbol.localeCompare(b.symbol);
28954
+ });
28955
+ return records;
28956
+ }
28957
+ function resolveCompilerOptions(packageRoot, tsconfigPath) {
28958
+ if (tsconfigPath) {
28959
+ const absoluteTsconfig = path3.resolve(packageRoot, tsconfigPath);
28960
+ const configFile = ts.readConfigFile(absoluteTsconfig, ts.sys.readFile);
28961
+ if (configFile.error) {
28962
+ throw new Error(
28963
+ `analyzeTsDocCoverage: failed to read tsconfig at ${absoluteTsconfig}: ${ts.flattenDiagnosticMessageText(configFile.error.messageText, "\n")}`
28964
+ );
28965
+ }
28966
+ const parsed = ts.parseJsonConfigFileContent(
28967
+ configFile.config,
28968
+ ts.sys,
28969
+ path3.dirname(absoluteTsconfig)
28970
+ );
28971
+ return { ...parsed.options, noEmit: true };
28972
+ }
28973
+ return {
28974
+ target: ts.ScriptTarget.ESNext,
28975
+ module: ts.ModuleKind.NodeNext,
28976
+ moduleResolution: ts.ModuleResolutionKind.NodeNext,
28977
+ allowJs: false,
28978
+ declaration: false,
28979
+ noEmit: true,
28980
+ skipLibCheck: true,
28981
+ strict: false,
28982
+ esModuleInterop: true,
28983
+ resolveJsonModule: true
28984
+ };
28985
+ }
28986
+ function resolveAlias(symbol, checker) {
28987
+ let current = symbol;
28988
+ for (let i = 0; i < 32; i++) {
28989
+ if (!isAlias(current)) {
28990
+ return current;
28991
+ }
28992
+ const next = checker.getAliasedSymbol(current);
28993
+ if (!next || next === current) {
28994
+ return current;
28995
+ }
28996
+ current = next;
28997
+ }
28998
+ return current;
28999
+ }
29000
+ function isAlias(symbol) {
29001
+ return (symbol.flags & ts.SymbolFlags.Alias) !== 0;
29002
+ }
29003
+ function pickPrimaryDeclaration(symbol) {
29004
+ const declarations = symbol.getDeclarations();
29005
+ if (!declarations || declarations.length === 0) {
29006
+ return void 0;
29007
+ }
29008
+ const concrete = declarations.find(
29009
+ (d) => !ts.isExportSpecifier(d) && !ts.isExportAssignment(d) && !ts.isExportDeclaration(d)
29010
+ );
29011
+ return concrete ?? declarations[0];
29012
+ }
29013
+ function classifyDeclaration(declaration) {
29014
+ if (ts.isClassDeclaration(declaration)) {
29015
+ return TsDocCoverageKind.Class;
29016
+ }
29017
+ if (ts.isInterfaceDeclaration(declaration)) {
29018
+ return TsDocCoverageKind.Interface;
29019
+ }
29020
+ if (ts.isTypeAliasDeclaration(declaration)) {
29021
+ return TsDocCoverageKind.TypeAlias;
29022
+ }
29023
+ if (ts.isEnumDeclaration(declaration)) {
29024
+ return TsDocCoverageKind.Enum;
29025
+ }
29026
+ if (ts.isFunctionDeclaration(declaration) || ts.isMethodDeclaration(declaration)) {
29027
+ return TsDocCoverageKind.Function;
29028
+ }
29029
+ if (ts.isVariableDeclaration(declaration) || ts.isVariableStatement(declaration)) {
29030
+ return TsDocCoverageKind.Variable;
29031
+ }
29032
+ if (ts.isModuleDeclaration(declaration)) {
29033
+ return TsDocCoverageKind.Module;
29034
+ }
29035
+ if (ts.isExportAssignment(declaration)) {
29036
+ return TsDocCoverageKind.Default;
29037
+ }
29038
+ return TsDocCoverageKind.Other;
29039
+ }
29040
+ function resolveLocation(declaration) {
29041
+ const target = ts.isVariableDeclaration(declaration) ? declaration.parent.parent ?? declaration : declaration;
29042
+ const source = target.getSourceFile();
29043
+ const { line } = source.getLineAndCharacterOfPosition(target.getStart());
29044
+ return { file: source.fileName, line: line + 1 };
29045
+ }
29046
+ function parseTsDocFor(declaration, parser) {
29047
+ const target = ts.isVariableDeclaration(declaration) ? declaration.parent.parent ?? declaration : declaration;
29048
+ const sourceText = target.getSourceFile().getFullText();
29049
+ const ranges = ts.getLeadingCommentRanges(sourceText, target.getFullStart());
29050
+ if (!ranges || ranges.length === 0) {
29051
+ return void 0;
29052
+ }
29053
+ for (let i = ranges.length - 1; i >= 0; i--) {
29054
+ const range = ranges[i];
29055
+ if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
29056
+ continue;
29057
+ }
29058
+ const text = sourceText.slice(range.pos, range.end);
29059
+ if (!text.startsWith("/**")) {
29060
+ continue;
29061
+ }
29062
+ const parsed = parser.parseString(text);
29063
+ return parsed.docComment;
29064
+ }
29065
+ return void 0;
29066
+ }
29067
+ function countSummaryWords(doc) {
29068
+ let words = 0;
29069
+ doc.summarySection.nodes.forEach((node) => {
29070
+ words += countWordsInNode(node);
29071
+ });
29072
+ return words;
29073
+ }
29074
+ function countWordsInNode(node) {
29075
+ const anyNode = node;
29076
+ if (anyNode.kind === "PlainText" && typeof anyNode.text === "string") {
29077
+ return anyNode.text.split(/\s+/).filter((token) => token.trim().length > 0).length;
29078
+ }
29079
+ let words = 0;
29080
+ const children = anyNode.getChildNodes?.() ?? [];
29081
+ for (const child of children) {
29082
+ words += countWordsInNode(child);
29083
+ }
29084
+ return words;
29085
+ }
29086
+ function hasBlockTag(doc, tagName) {
29087
+ if (tagName === "@param") {
29088
+ return doc.params.count > 0;
29089
+ }
29090
+ if (tagName === "@returns" || tagName === "@return") {
29091
+ return doc.returnsBlock !== void 0;
29092
+ }
29093
+ return doc.customBlocks.some((block) => block.blockTag.tagName === tagName);
29094
+ }
29095
+
28756
29096
  // src/latest-eligible-version.ts
28757
29097
  var NPM_REGISTRY = "https://registry.npmjs.org";
28758
29098
  function isPrerelease(version) {
@@ -28934,14 +29274,14 @@ var LAYOUT_ROOT_BY_PROJECT_TYPE = {
28934
29274
  };
28935
29275
  function validateMonorepoLayout(root) {
28936
29276
  const violations = [];
28937
- const rootOutdir = toPosix(root.outdir);
29277
+ const rootOutdir = toPosix2(root.outdir);
28938
29278
  for (const sub of root.subprojects) {
28939
29279
  const className = sub.constructor.name;
28940
29280
  const expectedRoot = expectedRootFor(sub, className);
28941
29281
  if (expectedRoot === void 0) {
28942
29282
  continue;
28943
29283
  }
28944
- const relOutdir = relativeOutdir(rootOutdir, toPosix(sub.outdir));
29284
+ const relOutdir = relativeOutdir(rootOutdir, toPosix2(sub.outdir));
28945
29285
  if (!outdirMatchesRoot(relOutdir, expectedRoot)) {
28946
29286
  violations.push({
28947
29287
  projectName: sub.name,
@@ -29000,7 +29340,7 @@ function outdirMatchesRoot(relOutdir, expectedRoot) {
29000
29340
  }
29001
29341
  return segments.length >= 2;
29002
29342
  }
29003
- function toPosix(p) {
29343
+ function toPosix2(p) {
29004
29344
  return p.replace(/\\/g, "/");
29005
29345
  }
29006
29346
  function relativeOutdir(rootOutdir, subOutdir) {
@@ -29080,8 +29420,8 @@ var ResetTask = class _ResetTask extends import_projen14.Component {
29080
29420
  const resetTask = this.project.tasks.addTask(this.taskName, {
29081
29421
  description: "Delete build artifacts specified by pathsToRemove option, or artifactsDirectory if pathsToRemove is empty"
29082
29422
  });
29083
- this.pathsToRemove.forEach((path2) => {
29084
- resetTask.exec(`[ -e "${path2}" ] && rm -rf ${path2} || true`);
29423
+ this.pathsToRemove.forEach((path4) => {
29424
+ resetTask.exec(`[ -e "${path4}" ] && rm -rf ${path4} || true`);
29085
29425
  });
29086
29426
  const rootHasTurbo = TurboRepo.of(this.project.root) !== void 0;
29087
29427
  const isSubproject = this.project !== this.project.root;
@@ -31099,6 +31439,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
31099
31439
  STARLIGHT_ROLE,
31100
31440
  StarlightProject,
31101
31441
  TestRunner,
31442
+ TsDocCoverageKind,
31102
31443
  TurboRepo,
31103
31444
  TurboRepoTask,
31104
31445
  TypeScriptConfig,
@@ -31113,6 +31454,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
31113
31454
  addBuildCompleteJob,
31114
31455
  addSyncLabelsWorkflow,
31115
31456
  agendaBundle,
31457
+ analyzeTsDocCoverage,
31116
31458
  awsCdkBundle,
31117
31459
  baseBundle,
31118
31460
  bcmWriterBundle,
@@ -31143,6 +31485,7 @@ var TypeScriptConfig = class extends import_projen23.Component {
31143
31485
  customerProfileBundle,
31144
31486
  docsSyncBundle,
31145
31487
  extractApiProcedure,
31488
+ extractDocReferences,
31146
31489
  formatLayoutViolation,
31147
31490
  formatStarlightSingletonViolation,
31148
31491
  getLatestEligibleVersion,