@outfitter/tooling 0.3.0 → 0.3.3
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/dist/cli/index.js +3 -6
- package/package.json +3 -2
- package/registry/registry.json +3 -3
- package/dist/cli/check-boundary-invocations.d.ts +0 -34
- package/dist/cli/check-boundary-invocations.js +0 -14
- package/dist/cli/check-bunup-registry.d.ts +0 -36
- package/dist/cli/check-bunup-registry.js +0 -12
- package/dist/cli/check-changeset.d.ts +0 -66
- package/dist/cli/check-changeset.js +0 -20
- package/dist/cli/check-clean-tree.d.ts +0 -36
- package/dist/cli/check-clean-tree.js +0 -14
- package/dist/cli/check-exports.d.ts +0 -2
- package/dist/cli/check-exports.js +0 -14
- package/dist/cli/check-readme-imports.d.ts +0 -61
- package/dist/cli/check-readme-imports.js +0 -198
- package/dist/cli/check-tsdoc.d.ts +0 -2
- package/dist/cli/check-tsdoc.js +0 -36
- package/dist/cli/check.d.ts +0 -19
- package/dist/cli/check.js +0 -10
- package/dist/cli/fix.d.ts +0 -19
- package/dist/cli/fix.js +0 -10
- package/dist/cli/init.d.ts +0 -31
- package/dist/cli/init.js +0 -12
- package/dist/cli/pre-push.d.ts +0 -48
- package/dist/cli/pre-push.js +0 -25
- package/dist/cli/upgrade-bun.d.ts +0 -8
- package/dist/cli/upgrade-bun.js +0 -8
- package/dist/registry/build.d.ts +0 -6
- package/dist/registry/build.js +0 -150
- package/dist/registry/index.d.ts +0 -3
- package/dist/registry/index.js +0 -13
- package/dist/registry/schema.d.ts +0 -2
- package/dist/registry/schema.js +0 -12
- package/dist/shared/@outfitter/tooling-0x5q15ec.js +0 -21
- package/dist/shared/@outfitter/tooling-1y8w5ahg.js +0 -70
- package/dist/shared/@outfitter/tooling-2n2dpsaa.js +0 -323
- package/dist/shared/@outfitter/tooling-9errkcvk.js +0 -21
- package/dist/shared/@outfitter/tooling-9vs606gq.d.ts +0 -3
- package/dist/shared/@outfitter/tooling-9yzd08v1.js +0 -146
- package/dist/shared/@outfitter/tooling-cj5vsa9k.js +0 -184
- package/dist/shared/@outfitter/tooling-ctmgnap5.js +0 -19
- package/dist/shared/@outfitter/tooling-dvwh9qve.js +0 -4
- package/dist/shared/@outfitter/tooling-enjcenja.js +0 -229
- package/dist/shared/@outfitter/tooling-kcvs6mys.js +0 -1
- package/dist/shared/@outfitter/tooling-mxwc1n8w.js +0 -68
- package/dist/shared/@outfitter/tooling-njw4z34x.d.ts +0 -140
- package/dist/shared/@outfitter/tooling-qk5xgmxr.js +0 -405
- package/dist/shared/@outfitter/tooling-r9976n43.js +0 -100
- package/dist/shared/@outfitter/tooling-sjm8nebx.d.ts +0 -109
- package/dist/shared/@outfitter/tooling-t17gnh9b.js +0 -78
- package/dist/shared/@outfitter/tooling-wesswf21.d.ts +0 -59
- package/dist/shared/@outfitter/tooling-wv09k6hr.js +0 -23
- package/dist/version.d.ts +0 -2
- package/dist/version.js +0 -8
package/dist/cli/index.js
CHANGED
|
@@ -348,10 +348,8 @@ async function runCheckChangeset(options = {}) {
|
|
|
348
348
|
const changesetFiles = getChangedChangesetFiles(changedFiles);
|
|
349
349
|
const check = checkChangesetRequired(changedPackages, changesetFiles);
|
|
350
350
|
if (!check.ok) {
|
|
351
|
-
process.stderr.write(`${COLORS2.
|
|
352
|
-
|
|
353
|
-
`);
|
|
354
|
-
process.stderr.write(`The following packages have source changes but no changeset:
|
|
351
|
+
process.stderr.write(`${COLORS2.yellow}No changeset found.${COLORS2.reset} ` + "Consider adding one with `bun run changeset` for a custom changelog entry.\n\n");
|
|
352
|
+
process.stderr.write(`Packages with source changes:
|
|
355
353
|
|
|
356
354
|
`);
|
|
357
355
|
for (const pkg of check.missingFor) {
|
|
@@ -359,9 +357,8 @@ async function runCheckChangeset(options = {}) {
|
|
|
359
357
|
`);
|
|
360
358
|
}
|
|
361
359
|
process.stderr.write(`
|
|
362
|
-
Run ${COLORS2.blue}bun run changeset${COLORS2.reset}
|
|
360
|
+
Run ${COLORS2.blue}bun run changeset${COLORS2.reset} for a custom changelog entry, ` + `or add ${COLORS2.blue}release:none${COLORS2.reset} to skip.
|
|
363
361
|
`);
|
|
364
|
-
process.exit(1);
|
|
365
362
|
}
|
|
366
363
|
const ignoredReferences = getIgnoredReferencesForChangedChangesets(cwd, changesetFiles);
|
|
367
364
|
if (ignoredReferences.length > 0) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@outfitter/tooling",
|
|
3
3
|
"description": "Dev tooling configuration presets for Outfitter projects (biome, typescript, lefthook, markdownlint)",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"prepack": "bun run sync:exports",
|
|
77
77
|
"lint": "biome lint ./src",
|
|
78
78
|
"lint:fix": "biome lint --write ./src",
|
|
79
|
-
"test": "bun test",
|
|
79
|
+
"test": "bun run build:registry && bun test",
|
|
80
80
|
"typecheck": "tsc --noEmit",
|
|
81
81
|
"clean": "rm -rf dist registry",
|
|
82
82
|
"prepublishOnly": "bun ../../scripts/check-publish-manifest.ts"
|
|
@@ -88,6 +88,7 @@
|
|
|
88
88
|
"zod": "^4.3.5"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
|
+
"@outfitter/presets": "0.2.0",
|
|
91
92
|
"@types/bun": "^1.3.9",
|
|
92
93
|
"yaml": "^2.8.2"
|
|
93
94
|
},
|
package/registry/registry.json
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
}
|
|
27
27
|
],
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"ultracite": "
|
|
29
|
+
"ultracite": "7.2.3"
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"lefthook": {
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
}
|
|
40
40
|
],
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@outfitter/tooling": "^0.
|
|
42
|
+
"@outfitter/tooling": "^0.3.3",
|
|
43
43
|
"lefthook": "^2.1.1",
|
|
44
|
-
"ultracite": "
|
|
44
|
+
"ultracite": "7.2.3"
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"markdownlint": {
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
interface ScriptLocation {
|
|
2
|
-
readonly file: string;
|
|
3
|
-
readonly scriptName: string;
|
|
4
|
-
readonly command: string;
|
|
5
|
-
}
|
|
6
|
-
interface BoundaryViolation extends ScriptLocation {
|
|
7
|
-
readonly rule: "root-runs-package-src" | "cd-package-then-runs-src";
|
|
8
|
-
}
|
|
9
|
-
interface ReadScriptEntriesOptions {
|
|
10
|
-
readonly appManifestRelativePaths?: readonly string[];
|
|
11
|
-
readonly readPackageJson?: (filePath: string) => Promise<{
|
|
12
|
-
scripts?: Record<string, string>;
|
|
13
|
-
}>;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Detect whether a single script command violates boundary invocation rules.
|
|
17
|
-
*/
|
|
18
|
-
declare function detectBoundaryViolation(location: ScriptLocation): BoundaryViolation | null;
|
|
19
|
-
/**
|
|
20
|
-
* Find all boundary violations across package/app script maps.
|
|
21
|
-
*/
|
|
22
|
-
declare function findBoundaryViolations(entries: readonly {
|
|
23
|
-
file: string;
|
|
24
|
-
scripts: Readonly<Record<string, string>>;
|
|
25
|
-
}[]): BoundaryViolation[];
|
|
26
|
-
declare function readScriptEntries(cwd: string, options?: ReadScriptEntriesOptions): Promise<{
|
|
27
|
-
file: string;
|
|
28
|
-
scripts: Record<string, string>;
|
|
29
|
-
}[]>;
|
|
30
|
-
/**
|
|
31
|
-
* Run boundary invocation checks against root/apps package scripts.
|
|
32
|
-
*/
|
|
33
|
-
declare function runCheckBoundaryInvocations(): Promise<void>;
|
|
34
|
-
export { runCheckBoundaryInvocations, readScriptEntries, findBoundaryViolations, detectBoundaryViolation, ScriptLocation, BoundaryViolation };
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
detectBoundaryViolation,
|
|
4
|
-
findBoundaryViolations,
|
|
5
|
-
readScriptEntries,
|
|
6
|
-
runCheckBoundaryInvocations
|
|
7
|
-
} from "../shared/@outfitter/tooling-r9976n43.js";
|
|
8
|
-
import"../shared/@outfitter/tooling-dvwh9qve.js";
|
|
9
|
-
export {
|
|
10
|
-
runCheckBoundaryInvocations,
|
|
11
|
-
readScriptEntries,
|
|
12
|
-
findBoundaryViolations,
|
|
13
|
-
detectBoundaryViolation
|
|
14
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/** Result of checking bunup workspace registration */
|
|
2
|
-
interface RegistryCheckResult {
|
|
3
|
-
readonly ok: boolean;
|
|
4
|
-
readonly missing: string[];
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Extract the package name from a build script containing `bunup --filter`.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* extractBunupFilterName("bunup --filter @outfitter/logging")
|
|
11
|
-
* // => "@outfitter/logging"
|
|
12
|
-
*
|
|
13
|
-
* extractBunupFilterName("cd ../.. && bunup --filter @outfitter/types")
|
|
14
|
-
* // => "@outfitter/types"
|
|
15
|
-
*
|
|
16
|
-
* extractBunupFilterName("tsc --noEmit")
|
|
17
|
-
* // => null
|
|
18
|
-
*/
|
|
19
|
-
declare function extractBunupFilterName(script: string): string | null;
|
|
20
|
-
/**
|
|
21
|
-
* Find packages that have `bunup --filter` build scripts but are not
|
|
22
|
-
* registered in the bunup workspace config.
|
|
23
|
-
*
|
|
24
|
-
* @param packagesWithFilter - Package names that have `bunup --filter` in their build script
|
|
25
|
-
* @param registeredNames - Package names registered in bunup.config.ts
|
|
26
|
-
* @returns Result with sorted list of missing packages
|
|
27
|
-
*/
|
|
28
|
-
declare function findUnregisteredPackages(packagesWithFilter: string[], registeredNames: string[]): RegistryCheckResult;
|
|
29
|
-
/**
|
|
30
|
-
* Run bunup registry check across all workspace packages.
|
|
31
|
-
*
|
|
32
|
-
* Scans packages/*/package.json for build scripts containing `bunup --filter`,
|
|
33
|
-
* then verifies each is registered in bunup.config.ts.
|
|
34
|
-
*/
|
|
35
|
-
declare function runCheckBunupRegistry(): Promise<void>;
|
|
36
|
-
export { runCheckBunupRegistry, findUnregisteredPackages, extractBunupFilterName, RegistryCheckResult };
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
extractBunupFilterName,
|
|
4
|
-
findUnregisteredPackages,
|
|
5
|
-
runCheckBunupRegistry
|
|
6
|
-
} from "../shared/@outfitter/tooling-t17gnh9b.js";
|
|
7
|
-
import"../shared/@outfitter/tooling-dvwh9qve.js";
|
|
8
|
-
export {
|
|
9
|
-
runCheckBunupRegistry,
|
|
10
|
-
findUnregisteredPackages,
|
|
11
|
-
extractBunupFilterName
|
|
12
|
-
};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/** Result of checking whether changesets are required */
|
|
2
|
-
interface ChangesetCheckResult {
|
|
3
|
-
readonly ok: boolean;
|
|
4
|
-
readonly missingFor: string[];
|
|
5
|
-
}
|
|
6
|
-
interface ChangesetIgnoredReference {
|
|
7
|
-
readonly file: string;
|
|
8
|
-
readonly packages: string[];
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Extract unique package names from changed file paths.
|
|
12
|
-
*
|
|
13
|
-
* Only considers files matching the pattern "packages/NAME/src/..." and
|
|
14
|
-
* ignores apps/, root files, and package-level config.
|
|
15
|
-
*
|
|
16
|
-
* @param files - List of changed file paths relative to repo root
|
|
17
|
-
* @returns Sorted array of unique package names
|
|
18
|
-
*/
|
|
19
|
-
declare function getChangedPackagePaths(files: string[]): string[];
|
|
20
|
-
/**
|
|
21
|
-
* Extract changeset filenames from changed file paths.
|
|
22
|
-
*
|
|
23
|
-
* Only considers files matching `.changeset/*.md`, excluding README.md.
|
|
24
|
-
* This checks the git diff rather than disk, ensuring only changesets added
|
|
25
|
-
* in the current PR are counted.
|
|
26
|
-
*
|
|
27
|
-
* @param files - List of changed file paths relative to repo root
|
|
28
|
-
* @returns Array of changeset filenames (e.g. `["happy-turtle.md"]`)
|
|
29
|
-
*/
|
|
30
|
-
declare function getChangedChangesetFiles(files: string[]): string[];
|
|
31
|
-
/**
|
|
32
|
-
* Determine whether a changeset is required and present.
|
|
33
|
-
*
|
|
34
|
-
* Returns `ok: true` when either no packages were changed or at least one
|
|
35
|
-
* changeset file exists. Returns `ok: false` with the list of changed
|
|
36
|
-
* packages when changesets are missing.
|
|
37
|
-
*
|
|
38
|
-
* @param changedPackages - Package names with source changes
|
|
39
|
-
* @param changesetFiles - Changeset filenames found in `.changeset/`
|
|
40
|
-
*/
|
|
41
|
-
declare function checkChangesetRequired(changedPackages: string[], changesetFiles: string[]): ChangesetCheckResult;
|
|
42
|
-
declare function parseIgnoredPackagesFromChangesetConfig(jsonContent: string): string[];
|
|
43
|
-
declare function parseChangesetFrontmatterPackageNames(markdownContent: string): string[];
|
|
44
|
-
declare function findIgnoredPackageReferences(input: {
|
|
45
|
-
readonly changesetFiles: readonly string[];
|
|
46
|
-
readonly ignoredPackages: readonly string[];
|
|
47
|
-
readonly readChangesetFile: (filename: string) => string;
|
|
48
|
-
}): ChangesetIgnoredReference[];
|
|
49
|
-
interface CheckChangesetOptions {
|
|
50
|
-
readonly skip?: boolean;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Run check-changeset to verify PRs include changeset files.
|
|
54
|
-
*
|
|
55
|
-
* Uses `git diff --name-only origin/main...HEAD` to detect changed files,
|
|
56
|
-
* then checks for changeset presence when package source files are modified.
|
|
57
|
-
*
|
|
58
|
-
* Skips silently when:
|
|
59
|
-
* - `NO_CHANGESET=1` env var is set
|
|
60
|
-
* - `--skip` flag is passed
|
|
61
|
-
* - `GITHUB_EVENT_NAME=push` (post-merge on main)
|
|
62
|
-
* - No packages have source changes
|
|
63
|
-
* - Git diff fails (local dev without origin)
|
|
64
|
-
*/
|
|
65
|
-
declare function runCheckChangeset(options?: CheckChangesetOptions): Promise<void>;
|
|
66
|
-
export { runCheckChangeset, parseIgnoredPackagesFromChangesetConfig, parseChangesetFrontmatterPackageNames, getChangedPackagePaths, getChangedChangesetFiles, findIgnoredPackageReferences, checkChangesetRequired, CheckChangesetOptions, ChangesetIgnoredReference, ChangesetCheckResult };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
checkChangesetRequired,
|
|
4
|
-
findIgnoredPackageReferences,
|
|
5
|
-
getChangedChangesetFiles,
|
|
6
|
-
getChangedPackagePaths,
|
|
7
|
-
parseChangesetFrontmatterPackageNames,
|
|
8
|
-
parseIgnoredPackagesFromChangesetConfig,
|
|
9
|
-
runCheckChangeset
|
|
10
|
-
} from "../shared/@outfitter/tooling-cj5vsa9k.js";
|
|
11
|
-
import"../shared/@outfitter/tooling-dvwh9qve.js";
|
|
12
|
-
export {
|
|
13
|
-
runCheckChangeset,
|
|
14
|
-
parseIgnoredPackagesFromChangesetConfig,
|
|
15
|
-
parseChangesetFrontmatterPackageNames,
|
|
16
|
-
getChangedPackagePaths,
|
|
17
|
-
getChangedChangesetFiles,
|
|
18
|
-
findIgnoredPackageReferences,
|
|
19
|
-
checkChangesetRequired
|
|
20
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check-clean-tree command — asserts the working tree has no modified or untracked files.
|
|
3
|
-
*
|
|
4
|
-
* Pure core functions for parsing git output and determining tree cleanliness.
|
|
5
|
-
* The CLI runner in {@link runCheckCleanTree} handles git invocation and output.
|
|
6
|
-
*
|
|
7
|
-
* @packageDocumentation
|
|
8
|
-
*/
|
|
9
|
-
/** Status of the working tree after verification steps */
|
|
10
|
-
interface TreeStatus {
|
|
11
|
-
readonly clean: boolean;
|
|
12
|
-
readonly modified: string[];
|
|
13
|
-
readonly untracked: string[];
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Parse `git diff --name-only` output into a list of modified file paths.
|
|
17
|
-
*/
|
|
18
|
-
declare function parseGitDiff(diffOutput: string): string[];
|
|
19
|
-
/**
|
|
20
|
-
* Parse `git ls-files --others --exclude-standard` output into a list of untracked file paths.
|
|
21
|
-
*/
|
|
22
|
-
declare function parseUntrackedFiles(lsOutput: string): string[];
|
|
23
|
-
/**
|
|
24
|
-
* Determine if the tree status represents a clean working tree.
|
|
25
|
-
*/
|
|
26
|
-
declare function isCleanTree(status: TreeStatus): boolean;
|
|
27
|
-
interface CheckCleanTreeOptions {
|
|
28
|
-
readonly paths?: string[];
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Run clean-tree check against the current working directory.
|
|
32
|
-
*
|
|
33
|
-
* Exits 0 if clean, 1 if dirty files are found.
|
|
34
|
-
*/
|
|
35
|
-
declare function runCheckCleanTree(options?: CheckCleanTreeOptions): Promise<void>;
|
|
36
|
-
export { runCheckCleanTree, parseUntrackedFiles, parseGitDiff, isCleanTree, TreeStatus, CheckCleanTreeOptions };
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
isCleanTree,
|
|
4
|
-
parseGitDiff,
|
|
5
|
-
parseUntrackedFiles,
|
|
6
|
-
runCheckCleanTree
|
|
7
|
-
} from "../shared/@outfitter/tooling-1y8w5ahg.js";
|
|
8
|
-
import"../shared/@outfitter/tooling-dvwh9qve.js";
|
|
9
|
-
export {
|
|
10
|
-
runCheckCleanTree,
|
|
11
|
-
parseUntrackedFiles,
|
|
12
|
-
parseGitDiff,
|
|
13
|
-
isCleanTree
|
|
14
|
-
};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { CheckExportsOptions, CheckResult, CompareInput, ExportDrift, ExportMap, PackageResult, compareExports, entryToSubpath, resolveJsonMode, runCheckExports } from "../shared/@outfitter/tooling-wesswf21.js";
|
|
2
|
-
export { runCheckExports, resolveJsonMode, entryToSubpath, compareExports, PackageResult, ExportMap, ExportDrift, CompareInput, CheckResult, CheckExportsOptions };
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
compareExports,
|
|
4
|
-
entryToSubpath,
|
|
5
|
-
resolveJsonMode,
|
|
6
|
-
runCheckExports
|
|
7
|
-
} from "../shared/@outfitter/tooling-enjcenja.js";
|
|
8
|
-
import"../shared/@outfitter/tooling-dvwh9qve.js";
|
|
9
|
-
export {
|
|
10
|
-
runCheckExports,
|
|
11
|
-
resolveJsonMode,
|
|
12
|
-
entryToSubpath,
|
|
13
|
-
compareExports
|
|
14
|
-
};
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { ExportMap } from "../shared/@outfitter/tooling-wesswf21.js";
|
|
2
|
-
/** An import example extracted from a markdown code block */
|
|
3
|
-
interface ImportExample {
|
|
4
|
-
/** Package name, e.g. "@outfitter/cli" */
|
|
5
|
-
readonly packageName: string;
|
|
6
|
-
/** Export subpath, e.g. "./output" or "." */
|
|
7
|
-
readonly subpath: string;
|
|
8
|
-
/** Full import specifier, e.g. "@outfitter/cli/output" */
|
|
9
|
-
readonly fullSpecifier: string;
|
|
10
|
-
/** File where the import was found */
|
|
11
|
-
readonly file: string;
|
|
12
|
-
/** 1-based line number */
|
|
13
|
-
readonly line: number;
|
|
14
|
-
}
|
|
15
|
-
/** Result of checking imports in a single file */
|
|
16
|
-
interface ImportCheckResult {
|
|
17
|
-
readonly file: string;
|
|
18
|
-
readonly valid: ImportExample[];
|
|
19
|
-
readonly invalid: ImportExample[];
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Parse a full import specifier into package name and subpath.
|
|
23
|
-
*
|
|
24
|
-
* Only recognizes `@outfitter/*` scoped packages.
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* parseSpecifier("@outfitter/cli/output")
|
|
28
|
-
* // { packageName: "@outfitter/cli", subpath: "./output" }
|
|
29
|
-
*
|
|
30
|
-
* parseSpecifier("@outfitter/contracts")
|
|
31
|
-
* // { packageName: "@outfitter/contracts", subpath: "." }
|
|
32
|
-
*/
|
|
33
|
-
declare function parseSpecifier(specifier: string): {
|
|
34
|
-
packageName: string;
|
|
35
|
-
subpath: string;
|
|
36
|
-
} | null;
|
|
37
|
-
/**
|
|
38
|
-
* Extract import specifiers from markdown content.
|
|
39
|
-
*
|
|
40
|
-
* Only extracts imports from fenced code blocks (typescript, ts,
|
|
41
|
-
* javascript, js). Skips blocks preceded by a non-contractual HTML comment.
|
|
42
|
-
* Deduplicates by full specifier within a single file.
|
|
43
|
-
*/
|
|
44
|
-
declare function extractImports(content: string, file: string): ImportExample[];
|
|
45
|
-
/**
|
|
46
|
-
* Check whether a subpath exists in a package.json map.
|
|
47
|
-
*/
|
|
48
|
-
declare function isExportedSubpath(subpath: string, exports: ExportMap): boolean;
|
|
49
|
-
interface CheckReadmeImportsOptions {
|
|
50
|
-
readonly json?: boolean;
|
|
51
|
-
}
|
|
52
|
-
declare function resolveJsonMode(options?: CheckReadmeImportsOptions): boolean;
|
|
53
|
-
/**
|
|
54
|
-
* Run check-readme-imports across all workspace packages.
|
|
55
|
-
*
|
|
56
|
-
* Finds README.md files in `packages/` and `docs/packages/`, extracts
|
|
57
|
-
* import examples, and validates each subpath against the corresponding
|
|
58
|
-
* package.json exports.
|
|
59
|
-
*/
|
|
60
|
-
declare function runCheckReadmeImports(options?: CheckReadmeImportsOptions): Promise<void>;
|
|
61
|
-
export { runCheckReadmeImports, resolveJsonMode, parseSpecifier, isExportedSubpath, extractImports, ImportExample, ImportCheckResult, ExportMap, CheckReadmeImportsOptions };
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import"../shared/@outfitter/tooling-dvwh9qve.js";
|
|
3
|
-
|
|
4
|
-
// packages/tooling/src/cli/check-readme-imports.ts
|
|
5
|
-
import { resolve } from "path";
|
|
6
|
-
function parseSpecifier(specifier) {
|
|
7
|
-
if (!specifier.startsWith("@outfitter/")) {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
const parts = specifier.split("/");
|
|
11
|
-
if (parts.length < 2) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
const packageName = `${parts[0]}/${parts[1]}`;
|
|
15
|
-
const rest = parts.slice(2);
|
|
16
|
-
if (rest.length === 0) {
|
|
17
|
-
return { packageName, subpath: "." };
|
|
18
|
-
}
|
|
19
|
-
return { packageName, subpath: `./${rest.join("/")}` };
|
|
20
|
-
}
|
|
21
|
-
function extractImports(content, file) {
|
|
22
|
-
const lines = content.split(`
|
|
23
|
-
`);
|
|
24
|
-
const results = [];
|
|
25
|
-
const seen = new Set;
|
|
26
|
-
const CODE_FENCE_OPEN = /^```(?:typescript|ts|javascript|js)\s*$/;
|
|
27
|
-
const CODE_FENCE_CLOSE = /^```\s*$/;
|
|
28
|
-
const IMPORT_RE = /from\s+["'](@outfitter\/[^"']+)["']/;
|
|
29
|
-
const NON_CONTRACTUAL = /<!--\s*non-contractual\s*-->/;
|
|
30
|
-
let inCodeBlock = false;
|
|
31
|
-
let skipBlock = false;
|
|
32
|
-
for (let i = 0;i < lines.length; i++) {
|
|
33
|
-
const line = lines[i];
|
|
34
|
-
if (!inCodeBlock) {
|
|
35
|
-
if (CODE_FENCE_OPEN.test(line)) {
|
|
36
|
-
inCodeBlock = true;
|
|
37
|
-
skipBlock = false;
|
|
38
|
-
for (let j = i - 1;j >= 0; j--) {
|
|
39
|
-
const prev = lines[j].trim();
|
|
40
|
-
if (prev === "")
|
|
41
|
-
continue;
|
|
42
|
-
if (NON_CONTRACTUAL.test(prev)) {
|
|
43
|
-
skipBlock = true;
|
|
44
|
-
}
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
if (CODE_FENCE_CLOSE.test(line) && !CODE_FENCE_OPEN.test(line)) {
|
|
51
|
-
inCodeBlock = false;
|
|
52
|
-
skipBlock = false;
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (skipBlock)
|
|
56
|
-
continue;
|
|
57
|
-
const match = IMPORT_RE.exec(line);
|
|
58
|
-
if (!match?.[1])
|
|
59
|
-
continue;
|
|
60
|
-
const fullSpecifier = match[1];
|
|
61
|
-
if (seen.has(fullSpecifier))
|
|
62
|
-
continue;
|
|
63
|
-
seen.add(fullSpecifier);
|
|
64
|
-
const parsed = parseSpecifier(fullSpecifier);
|
|
65
|
-
if (!parsed)
|
|
66
|
-
continue;
|
|
67
|
-
results.push({
|
|
68
|
-
packageName: parsed.packageName,
|
|
69
|
-
subpath: parsed.subpath,
|
|
70
|
-
fullSpecifier,
|
|
71
|
-
file,
|
|
72
|
-
line: i + 1
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
return results;
|
|
76
|
-
}
|
|
77
|
-
function isExportedSubpath(subpath, exports) {
|
|
78
|
-
return subpath in exports;
|
|
79
|
-
}
|
|
80
|
-
var COLORS = {
|
|
81
|
-
reset: "\x1B[0m",
|
|
82
|
-
red: "\x1B[31m",
|
|
83
|
-
green: "\x1B[32m",
|
|
84
|
-
yellow: "\x1B[33m",
|
|
85
|
-
blue: "\x1B[34m",
|
|
86
|
-
dim: "\x1B[2m"
|
|
87
|
-
};
|
|
88
|
-
function resolveJsonMode(options = {}) {
|
|
89
|
-
return options.json ?? process.env["OUTFITTER_JSON"] === "1";
|
|
90
|
-
}
|
|
91
|
-
async function runCheckReadmeImports(options = {}) {
|
|
92
|
-
const cwd = process.cwd();
|
|
93
|
-
const readmeGlob = new Bun.Glob("**/README.md");
|
|
94
|
-
const readmeDirs = ["packages", "docs/packages"];
|
|
95
|
-
const readmePaths = [];
|
|
96
|
-
for (const dir of readmeDirs) {
|
|
97
|
-
const fullDir = resolve(cwd, dir);
|
|
98
|
-
try {
|
|
99
|
-
for (const match of readmeGlob.scanSync({ cwd: fullDir, dot: false })) {
|
|
100
|
-
const segments = match.split("/");
|
|
101
|
-
if (segments.length === 2 && segments[1] === "README.md") {
|
|
102
|
-
readmePaths.push(resolve(fullDir, match));
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
} catch {}
|
|
106
|
-
}
|
|
107
|
-
if (readmePaths.length === 0) {
|
|
108
|
-
process.stdout.write(`No README.md files found.
|
|
109
|
-
`);
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
const exportsCache = new Map;
|
|
113
|
-
async function getExportsForPackage(packageName) {
|
|
114
|
-
if (exportsCache.has(packageName)) {
|
|
115
|
-
return exportsCache.get(packageName) ?? null;
|
|
116
|
-
}
|
|
117
|
-
const shortName = packageName.replace("@outfitter/", "");
|
|
118
|
-
const pkgPath = resolve(cwd, "packages", shortName, "package.json");
|
|
119
|
-
try {
|
|
120
|
-
const pkg = await Bun.file(pkgPath).json();
|
|
121
|
-
const exports = typeof pkg.exports === "object" && pkg.exports !== null ? pkg.exports : {};
|
|
122
|
-
exportsCache.set(packageName, exports);
|
|
123
|
-
return exports;
|
|
124
|
-
} catch {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
const results = [];
|
|
129
|
-
let hasInvalid = false;
|
|
130
|
-
for (const readmePath of readmePaths.sort()) {
|
|
131
|
-
const content = await Bun.file(readmePath).text();
|
|
132
|
-
const relativePath = readmePath.replace(`${cwd}/`, "");
|
|
133
|
-
const imports = extractImports(content, relativePath);
|
|
134
|
-
if (imports.length === 0)
|
|
135
|
-
continue;
|
|
136
|
-
const valid = [];
|
|
137
|
-
const invalid = [];
|
|
138
|
-
for (const imp of imports) {
|
|
139
|
-
const exports = await getExportsForPackage(imp.packageName);
|
|
140
|
-
if (exports === null) {
|
|
141
|
-
invalid.push(imp);
|
|
142
|
-
continue;
|
|
143
|
-
}
|
|
144
|
-
if (isExportedSubpath(imp.subpath, exports)) {
|
|
145
|
-
valid.push(imp);
|
|
146
|
-
} else {
|
|
147
|
-
invalid.push(imp);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
if (valid.length > 0 || invalid.length > 0) {
|
|
151
|
-
results.push({ file: relativePath, valid, invalid });
|
|
152
|
-
}
|
|
153
|
-
if (invalid.length > 0) {
|
|
154
|
-
hasInvalid = true;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
if (resolveJsonMode(options)) {
|
|
158
|
-
const output = {
|
|
159
|
-
ok: !hasInvalid,
|
|
160
|
-
files: results
|
|
161
|
-
};
|
|
162
|
-
process.stdout.write(`${JSON.stringify(output, null, 2)}
|
|
163
|
-
`);
|
|
164
|
-
} else {
|
|
165
|
-
const totalValid = results.reduce((n, r) => n + r.valid.length, 0);
|
|
166
|
-
const totalInvalid = results.reduce((n, r) => n + r.invalid.length, 0);
|
|
167
|
-
if (!hasInvalid) {
|
|
168
|
-
process.stdout.write(`${COLORS.green}All ${totalValid} README import examples match package exports.${COLORS.reset}
|
|
169
|
-
`);
|
|
170
|
-
} else {
|
|
171
|
-
process.stderr.write(`${COLORS.red}Invalid README import examples found:${COLORS.reset}
|
|
172
|
-
|
|
173
|
-
`);
|
|
174
|
-
for (const result of results) {
|
|
175
|
-
if (result.invalid.length === 0)
|
|
176
|
-
continue;
|
|
177
|
-
process.stderr.write(` ${COLORS.yellow}${result.file}${COLORS.reset}
|
|
178
|
-
`);
|
|
179
|
-
for (const imp of result.invalid) {
|
|
180
|
-
process.stderr.write(` ${COLORS.red}line ${imp.line}:${COLORS.reset} ${imp.fullSpecifier} ${COLORS.dim}(subpath ${imp.subpath} not in ${imp.packageName} exports)${COLORS.reset}
|
|
181
|
-
`);
|
|
182
|
-
}
|
|
183
|
-
process.stderr.write(`
|
|
184
|
-
`);
|
|
185
|
-
}
|
|
186
|
-
process.stderr.write(`${totalInvalid} invalid, ${totalValid} valid across ${results.length} file(s).
|
|
187
|
-
`);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
process.exit(hasInvalid ? 1 : 0);
|
|
191
|
-
}
|
|
192
|
-
export {
|
|
193
|
-
runCheckReadmeImports,
|
|
194
|
-
resolveJsonMode,
|
|
195
|
-
parseSpecifier,
|
|
196
|
-
isExportedSubpath,
|
|
197
|
-
extractImports
|
|
198
|
-
};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { CheckTsDocOptions, CoverageLevel, CoverageSummary, DeclarationCoverage, PackageCoverage, TsDocCheckResult, analyzeCheckTsdoc, analyzeSourceFile, calculateCoverage, classifyDeclaration, coverageLevelSchema, coverageSummarySchema, declarationCoverageSchema, getDeclarationKind, getDeclarationName, isExportedDeclaration, packageCoverageSchema, printCheckTsdocHuman, resolveJsonMode, runCheckTsdoc, tsDocCheckResultSchema } from "../shared/@outfitter/tooling-njw4z34x.js";
|
|
2
|
-
export { tsDocCheckResultSchema, runCheckTsdoc, resolveJsonMode, printCheckTsdocHuman, packageCoverageSchema, isExportedDeclaration, getDeclarationName, getDeclarationKind, declarationCoverageSchema, coverageSummarySchema, coverageLevelSchema, classifyDeclaration, calculateCoverage, analyzeSourceFile, analyzeCheckTsdoc, TsDocCheckResult, PackageCoverage, DeclarationCoverage, CoverageSummary, CoverageLevel, CheckTsDocOptions };
|
package/dist/cli/check-tsdoc.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
analyzeCheckTsdoc,
|
|
4
|
-
analyzeSourceFile,
|
|
5
|
-
calculateCoverage,
|
|
6
|
-
classifyDeclaration,
|
|
7
|
-
coverageLevelSchema,
|
|
8
|
-
coverageSummarySchema,
|
|
9
|
-
declarationCoverageSchema,
|
|
10
|
-
getDeclarationKind,
|
|
11
|
-
getDeclarationName,
|
|
12
|
-
isExportedDeclaration,
|
|
13
|
-
packageCoverageSchema,
|
|
14
|
-
printCheckTsdocHuman,
|
|
15
|
-
resolveJsonMode,
|
|
16
|
-
runCheckTsdoc,
|
|
17
|
-
tsDocCheckResultSchema
|
|
18
|
-
} from "../shared/@outfitter/tooling-qk5xgmxr.js";
|
|
19
|
-
import"../shared/@outfitter/tooling-dvwh9qve.js";
|
|
20
|
-
export {
|
|
21
|
-
tsDocCheckResultSchema,
|
|
22
|
-
runCheckTsdoc,
|
|
23
|
-
resolveJsonMode,
|
|
24
|
-
printCheckTsdocHuman,
|
|
25
|
-
packageCoverageSchema,
|
|
26
|
-
isExportedDeclaration,
|
|
27
|
-
getDeclarationName,
|
|
28
|
-
getDeclarationKind,
|
|
29
|
-
declarationCoverageSchema,
|
|
30
|
-
coverageSummarySchema,
|
|
31
|
-
coverageLevelSchema,
|
|
32
|
-
classifyDeclaration,
|
|
33
|
-
calculateCoverage,
|
|
34
|
-
analyzeSourceFile,
|
|
35
|
-
analyzeCheckTsdoc
|
|
36
|
-
};
|
package/dist/cli/check.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI check command - Run linting checks (wraps ultracite)
|
|
3
|
-
*/
|
|
4
|
-
/** Options for the check command */
|
|
5
|
-
interface CheckOptions {
|
|
6
|
-
paths?: string[];
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Build the ultracite check command
|
|
10
|
-
* @param options - Command options
|
|
11
|
-
* @returns Array of command arguments
|
|
12
|
-
*/
|
|
13
|
-
declare function buildCheckCommand(options: CheckOptions): string[];
|
|
14
|
-
/**
|
|
15
|
-
* Run the check command
|
|
16
|
-
* @param paths - Paths to check
|
|
17
|
-
*/
|
|
18
|
-
declare function runCheck(paths?: string[]): Promise<void>;
|
|
19
|
-
export { runCheck, buildCheckCommand };
|