@stll/oxlint-config 1.3.0 → 1.4.0
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/README.md +254 -17
- package/dist/cloud-setup-cli.cjs +18 -38
- package/dist/cloud-setup-cli.cjs.map +1 -1
- package/dist/cloud-setup-cli.mjs +21 -41
- package/dist/cloud-setup-cli.mjs.map +1 -1
- package/dist/consumer-compat-cli.cjs +50 -249
- package/dist/consumer-compat-cli.cjs.map +1 -1
- package/dist/consumer-compat-cli.mjs +6 -205
- package/dist/consumer-compat-cli.mjs.map +1 -1
- package/dist/consumer-node-support.cjs +497 -0
- package/dist/consumer-node-support.cjs.map +1 -0
- package/dist/consumer-node-support.mjs +381 -0
- package/dist/consumer-node-support.mjs.map +1 -0
- package/dist/dependabot-cli.cjs +67 -0
- package/dist/dependabot-cli.cjs.map +1 -0
- package/dist/dependabot-cli.d.cts +1 -0
- package/dist/dependabot-cli.d.mts +1 -0
- package/dist/dependabot-cli.mjs +67 -0
- package/dist/dependabot-cli.mjs.map +1 -0
- package/dist/dependabot.cjs +5 -0
- package/dist/dependabot.d.cts +108 -0
- package/dist/dependabot.d.mts +108 -0
- package/dist/dependabot.mjs +3 -0
- package/dist/generated-file.cjs +61 -0
- package/dist/generated-file.cjs.map +1 -0
- package/dist/generated-file.mjs +44 -0
- package/dist/generated-file.mjs.map +1 -0
- package/dist/publish-artifact-syntax.cjs +1309 -0
- package/dist/publish-artifact-syntax.cjs.map +1 -0
- package/dist/publish-artifact-syntax.mjs +1265 -0
- package/dist/publish-artifact-syntax.mjs.map +1 -0
- package/dist/publish-contract-cli.cjs +53 -12
- package/dist/publish-contract-cli.cjs.map +1 -1
- package/dist/publish-contract-cli.mjs +49 -8
- package/dist/publish-contract-cli.mjs.map +1 -1
- package/dist/toolchain-changed.cjs +5 -1
- package/dist/toolchain-changed.cjs.map +1 -1
- package/dist/toolchain-changed.mjs +6 -2
- package/dist/toolchain-changed.mjs.map +1 -1
- package/dist/toolchain-dependabot.cjs +455 -0
- package/dist/toolchain-dependabot.cjs.map +1 -0
- package/dist/toolchain-dependabot.mjs +423 -0
- package/dist/toolchain-dependabot.mjs.map +1 -0
- package/dist/toolchain-guard.cjs +1096 -424
- package/dist/toolchain-guard.cjs.map +1 -1
- package/dist/toolchain-guard.mjs +1085 -413
- package/dist/toolchain-guard.mjs.map +1 -1
- package/dist/toolchain-inputs.cjs +122 -22
- package/dist/toolchain-inputs.cjs.map +1 -1
- package/dist/toolchain-inputs.mjs +117 -23
- package/dist/toolchain-inputs.mjs.map +1 -1
- package/dist/toolchain-schema.cjs +0 -493
- package/dist/toolchain-schema.cjs.map +1 -1
- package/dist/toolchain-schema.mjs +3 -379
- package/dist/toolchain-schema.mjs.map +1 -1
- package/dist/typecheck-parity.cjs +1 -1
- package/dist/typecheck-probe-cli.cjs +1 -1
- package/dist/typecheck-probe-cli.cjs.map +1 -1
- package/dist/typecheck-probe-cli.mjs +1 -1
- package/dist/typecheck-probe-cli.mjs.map +1 -1
- package/package.json +13 -1
- package/dist/publish-contract.cjs +0 -431
- package/dist/publish-contract.cjs.map +0 -1
- package/dist/publish-contract.mjs +0 -396
- package/dist/publish-contract.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolchain-schema.mjs","names":["record"],"sources":["../src/consumer-catalogs.ts","../src/consumer-compat-config.ts","../src/consumer-node-support.ts","../src/toolchain-schema.ts"],"sourcesContent":["import path from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport { parseDocument } from \"yaml\";\n\nimport { workspaceContains } from \"./toolchain-workspaces\";\n\nconst record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst catalogMapping = (value: unknown, field: string) => {\n if (!record(value)) throw new Error(`${field} must be a mapping`);\n const entries = new Map<string, string>();\n for (const [name, specifier] of Object.entries(value)) {\n if (name === \"\" || typeof specifier !== \"string\" || specifier.trim() === \"\")\n throw new Error(`${field} must contain nonempty package specifiers`);\n entries.set(name, specifier);\n }\n return Object.fromEntries(entries);\n};\n\nexport const catalogState = (source: Record<string, unknown>, file: string) => {\n const result: {\n catalog?: Record<string, string>;\n catalogs?: Record<string, Record<string, string>>;\n } = {};\n if (Object.hasOwn(source, \"catalog\"))\n result.catalog = catalogMapping(source[\"catalog\"], `${file}: catalog`);\n if (Object.hasOwn(source, \"catalogs\")) {\n if (!record(source[\"catalogs\"]))\n throw new Error(`${file}: catalogs must be a mapping`);\n const named = new Map<string, Record<string, string>>();\n for (const [name, entries] of Object.entries(source[\"catalogs\"])) {\n if (name === \"\")\n throw new Error(`${file}: catalog names must be nonempty`);\n named.set(name, catalogMapping(entries, `${file}: catalogs.${name}`));\n }\n result.catalogs = Object.fromEntries(named);\n }\n return result;\n};\n\nexport const bunCatalogState = (manifest: Record<string, unknown>) => {\n const sources = [manifest];\n if (record(manifest[\"workspaces\"])) sources.push(manifest[\"workspaces\"]);\n const merged: Record<string, unknown> = {};\n for (const source of sources) {\n const state = catalogState(source, \"package.json\");\n for (const [field, value] of Object.entries(state)) {\n if (\n Object.hasOwn(merged, field) &&\n !isDeepStrictEqual(merged[field], value)\n )\n throw new Error(`conflicting Bun ${field} definitions in package.json`);\n merged[field] = value;\n }\n }\n return catalogState(merged, \"package.json\");\n};\n\nexport const pnpmWorkspaceState = (source: string, file: string) => {\n const document = parseDocument(source, { uniqueKeys: true });\n if (document.errors.length !== 0)\n throw new Error(`invalid pnpm workspace: ${file}`);\n const workspace: unknown = document.toJS({ maxAliasCount: 100 });\n if (!record(workspace)) throw new Error(`invalid pnpm workspace: ${file}`);\n const packages = workspace[\"packages\"];\n if (\n packages !== undefined &&\n (!Array.isArray(packages) ||\n !packages.every((entry: unknown) => typeof entry === \"string\"))\n )\n throw new Error(`invalid pnpm workspace packages: ${file}`);\n return { packages: packages ?? [], ...catalogState(workspace, file) };\n};\n\ntype ResolveConsumerCatalogOptions = {\n directory: string;\n name: string;\n specifier: string;\n files: Record<string, string>;\n};\nexport const resolveConsumerCatalog = ({\n directory: inputDirectory,\n name,\n specifier,\n files,\n}: ResolveConsumerCatalogOptions) => {\n let directory = inputDirectory;\n while (true) {\n const yamlFile = path.posix.join(directory, \"pnpm-workspace.yaml\");\n const yaml = files[yamlFile];\n const manifestFile = path.posix.join(directory, \"package.json\");\n const json = files[manifestFile];\n let state: ReturnType<typeof catalogState> | undefined;\n let patterns: string[] = [];\n if (yaml !== undefined) {\n const workspace = pnpmWorkspaceState(yaml, yamlFile);\n state = catalogState(workspace, yamlFile);\n patterns = workspace.packages;\n } else if (json !== undefined) {\n const manifest: unknown = JSON.parse(json);\n if (!record(manifest))\n throw new Error(`invalid catalog owner: ${manifestFile}`);\n const declaration = manifest[\"workspaces\"];\n if (directory === \".\" || declaration !== undefined) {\n state = bunCatalogState(manifest);\n const packages = record(declaration)\n ? declaration[\"packages\"]\n : declaration;\n if (\n packages !== undefined &&\n (!Array.isArray(packages) ||\n !packages.every((entry: unknown) => typeof entry === \"string\"))\n )\n throw new Error(`invalid catalog owner packages: ${manifestFile}`);\n patterns = packages ?? [];\n }\n }\n if (state !== undefined) {\n if (\n !workspaceContains({\n directory,\n file: path.posix.join(inputDirectory, \"package.json\"),\n patterns,\n rootMembership: \"implicit\",\n })\n )\n throw new Error(\n `catalog dependency ${name} is outside nearest workspace owner ${directory}`,\n );\n const catalogName = specifier.slice(\"catalog:\".length) || \"default\";\n const named = state.catalogs;\n const namedEntries =\n named !== undefined && Object.hasOwn(named, catalogName)\n ? named[catalogName]\n : undefined;\n const entries =\n catalogName === \"default\"\n ? (state.catalog ?? namedEntries)\n : namedEntries;\n const resolved =\n entries !== undefined && Object.hasOwn(entries, name)\n ? entries[name]\n : undefined;\n if (resolved === undefined)\n throw new Error(\n `unresolved catalog dependency ${name} in workspace ${directory}`,\n );\n return resolved;\n }\n if (directory === \".\") break;\n directory = path.posix.dirname(directory);\n }\n throw new Error(\n `unresolved catalog dependency ${name}: no tracked workspace owner`,\n );\n};\n","import path from \"node:path\";\nimport picomatch from \"picomatch\";\nimport { compare, satisfies, valid, validRange } from \"semver\";\nimport { parseDocument } from \"yaml\";\n\nimport { resolveConsumerCatalog } from \"./consumer-catalogs\";\n\nexport const consumerFixtureKinds = [\"node\", \"react\"] as const;\nexport type ConsumerFixture = {\n package: string;\n fixture: string;\n kind: (typeof consumerFixtureKinds)[number];\n build: string[];\n smoke: string[];\n};\n\nexport const consumerRecord = (\n value: unknown,\n): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nexport const consumerRelativePath = (value: unknown, field: string) => {\n if (\n typeof value !== \"string\" ||\n value === \"\" ||\n value.includes(\"\\\\\") ||\n value.includes(\"\\0\") ||\n path.posix.isAbsolute(value) ||\n value.split(\"/\").some((part) => part === \"..\" || part === \"\")\n )\n throw new Error(`${field} must be a repository-relative path`);\n return path.posix.normalize(value);\n};\n\nconst command = (value: unknown, field: string) => {\n if (\n !Array.isArray(value) ||\n value.length === 0 ||\n !value.every(\n (part: unknown) =>\n typeof part === \"string\" && part !== \"\" && !part.includes(\"\\0\"),\n )\n )\n throw new Error(`${field} must be a nonempty command argument array`);\n return value.map((part: string) => part);\n};\n\nexport const parseConsumerFixtures = (input: unknown): ConsumerFixture[] => {\n if (\n !consumerRecord(input) ||\n Object.keys(input).some((key) => key !== \"packages\") ||\n !Array.isArray(input[\"packages\"])\n )\n throw new Error(\"consumer fixtures must contain only a packages array\");\n const seen = new Set<string>();\n return input[\"packages\"].map((entry: unknown) => {\n if (\n !consumerRecord(entry) ||\n Object.keys(entry).some(\n (key) =>\n ![\"package\", \"fixture\", \"kind\", \"build\", \"smoke\"].includes(key),\n )\n )\n throw new Error(\"invalid consumer fixture declaration\");\n const packagePath = consumerRelativePath(entry[\"package\"], \"package\");\n const fixture = consumerRelativePath(entry[\"fixture\"], \"fixture\");\n const kind = entry[\"kind\"];\n if (kind !== \"node\" && kind !== \"react\")\n throw new Error(\"fixture kind must be node or react\");\n if (seen.has(packagePath))\n throw new Error(`duplicate consumer fixture: ${packagePath}`);\n seen.add(packagePath);\n return {\n package: packagePath,\n fixture,\n kind,\n build: command(entry[\"build\"], \"build\"),\n smoke: command(entry[\"smoke\"], \"smoke\"),\n };\n });\n};\n\ntype ConsumerFixtureSelectionOptions = {\n selected: readonly string[];\n fixtures: readonly ConsumerFixture[];\n};\nexport const assertConsumerFixtureSelection = ({\n selected,\n fixtures,\n}: ConsumerFixtureSelectionOptions) => {\n const directories = selected.map((entry) =>\n consumerRelativePath(entry, \"selected package\"),\n );\n const declared = new Set(fixtures.map((entry) => entry.package));\n if (new Set(directories).size !== directories.length)\n throw new Error(\"duplicate selected consumer package\");\n if (\n directories.length !== declared.size ||\n directories.some((entry) => !declared.has(entry))\n )\n throw new Error(\n \"selected consumer packages must exactly match declared fixtures\",\n );\n};\n\nexport type ConsumerPackage = {\n directory: string;\n name: string;\n manifest: Record<string, unknown>;\n};\n\nexport const consumerBundledDependencyFields = [\n \"bundleDependencies\",\n \"bundledDependencies\",\n] as const;\n\nconst consumerPackageNameValid = (value: unknown) => {\n if (typeof value !== \"string\" || value.length === 0 || value.length > 214)\n return false;\n const components = value.startsWith(\"@\")\n ? value.slice(1).split(\"/\")\n : [value];\n if (value.startsWith(\"@\") && components.length !== 2) return false;\n if (!value.startsWith(\"@\") && !/^[a-z0-9]/.test(value)) return false;\n if (\n components.some(\n (component) =>\n !/^[a-z0-9._-]+$/.test(component) ||\n component === \".\" ||\n component === \"..\",\n )\n )\n return false;\n const packageName = components.at(-1);\n return packageName !== \"node_modules\" && packageName !== \"favicon.ico\";\n};\n\nexport const assertConsumerPublishableManifest = ({\n manifest,\n directory,\n}: Pick<ConsumerPackage, \"manifest\" | \"directory\">) => {\n const version = manifest[\"version\"];\n if (\n manifest[\"private\"] !== true &&\n (typeof version !== \"string\" || valid(version) === null)\n )\n throw new Error(\n `public consumer package requires a semver-valid version: ${directory}`,\n );\n if (\n manifest[\"private\"] !== true &&\n !consumerPackageNameValid(manifest[\"name\"])\n )\n throw new Error(\n `public consumer package requires a valid npm name: ${directory}`,\n );\n for (const field of consumerBundledDependencyFields)\n if (Object.hasOwn(manifest, field))\n throw new Error(\n `consumer packaging does not support ${field}: ${directory}`,\n );\n};\n\ntype ConsumerFixtureKindOptions = {\n fixture: ConsumerFixture;\n pkg: ConsumerPackage;\n};\n\nexport const assertConsumerFixtureKind = ({\n fixture,\n pkg,\n}: ConsumerFixtureKindOptions) => {\n const peers = pkg.manifest[\"peerDependencies\"];\n if (peers !== undefined && !consumerRecord(peers))\n throw new Error(`invalid published peerDependencies: ${pkg.name}`);\n const react = consumerRecord(peers) ? peers[\"react\"] : undefined;\n if (\n react !== undefined &&\n (typeof react !== \"string\" ||\n react.trim() === \"\" ||\n validRange(react) === null)\n )\n throw new Error(`invalid published React peer: ${pkg.name}`);\n const kind = react === undefined ? \"node\" : \"react\";\n if (fixture.kind !== kind)\n throw new Error(\n `${pkg.name} requires fixture kind ${kind} from its published peers`,\n );\n};\n\nexport const consumerStagingPaths = (\n packages: Map<string, ConsumerPackage>,\n) => {\n const paths = new Map<string, string>();\n for (const [name, pkg] of packages)\n paths.set(\n name,\n consumerRelativePath(pkg.directory, \"workspace package directory\"),\n );\n return paths;\n};\n\nexport const consumerPackRootManifest = (\n packages: Map<string, ConsumerPackage>,\n files: Record<string, string>,\n) => {\n const source = files[\"package.json\"];\n if (source !== undefined) {\n const manifest: unknown = JSON.parse(source);\n if (!consumerRecord(manifest))\n throw new Error(\"root package manifest must be an object\");\n return manifest;\n }\n const root = [...packages.values()].find((pkg) => pkg.directory === \".\");\n return root?.manifest ?? { private: true };\n};\n\nexport const consumerDependencyConfigFiles = [\n \".npmrc\",\n \".pnpmfile.cjs\",\n \"pnpm-workspace.yaml\",\n \".yarnrc\",\n \".yarnrc.yml\",\n] as const;\n\nexport const assertConsumerFixtureManifest = (\n manifest: Record<string, unknown>,\n) => {\n for (const field of [\n \"pnpm\",\n \"overrides\",\n \"resolutions\",\n \"workspaces\",\n \"packageManager\",\n \"allowScripts\",\n ])\n if (manifest[field] !== undefined)\n throw new Error(\n `consumer fixture must not supply dependency-manager setting: ${field}`,\n );\n};\n\ntype BindConsumerManifestOptions = {\n manifest: Record<string, unknown>;\n artifacts: Map<string, string>;\n typescript: string;\n react: Record<string, string>;\n manager: \"npm\" | \"pnpm\";\n};\nexport const bindConsumerManifest = ({\n manifest,\n artifacts,\n typescript,\n react,\n manager,\n}: BindConsumerManifestOptions) => {\n assertConsumerFixtureManifest(manifest);\n const artifactBindings = Object.fromEntries(\n [...artifacts].map(([name, file]) => [name, `file:${file}`]),\n );\n const owned = { ...artifactBindings, typescript, ...react };\n const result = { ...manifest };\n for (const field of [\n \"dependencies\",\n \"devDependencies\",\n \"optionalDependencies\",\n \"peerDependencies\",\n ]) {\n const entries = manifest[field];\n if (entries === undefined) continue;\n if (!consumerRecord(entries))\n throw new Error(`fixture ${field} must be an object`);\n for (const specifier of Object.values(entries))\n if (\n typeof specifier !== \"string\" ||\n /^(?:workspace:|file:|link:|\\.\\.?\\/|\\/)/.test(specifier)\n )\n throw new Error(\n \"fixture dependencies must resolve from registry or generated artifact bindings\",\n );\n result[field] = Object.fromEntries(\n Object.entries(entries).filter(([name]) => !Object.hasOwn(owned, name)),\n );\n }\n result[\"dependencies\"] = {\n ...(consumerRecord(result[\"dependencies\"]) ? result[\"dependencies\"] : {}),\n ...artifactBindings,\n ...react,\n };\n result[\"devDependencies\"] = {\n ...(consumerRecord(result[\"devDependencies\"])\n ? result[\"devDependencies\"]\n : {}),\n typescript,\n };\n if (manager === \"npm\") {\n result[\"overrides\"] = owned;\n return { manager, manifest: result };\n }\n return {\n manager,\n manifest: result,\n workspace: { packages: [\".\"], overrides: owned },\n };\n};\n\nconst workspacePatterns = (manifest: Record<string, unknown>) => {\n const workspace = manifest[\"workspaces\"];\n const patterns = consumerRecord(workspace)\n ? workspace[\"packages\"]\n : workspace;\n if (patterns === undefined) return [];\n if (\n !Array.isArray(patterns) ||\n !patterns.every((entry: unknown) => typeof entry === \"string\")\n )\n throw new Error(\"package workspaces must be string patterns\");\n return patterns.map((entry: string) => entry);\n};\n\nexport const discoverConsumerManifests = (files: Record<string, string>) => {\n const manifests = new Map<string, Record<string, unknown>>();\n const manifestSources = new Map<string, string>();\n const pnpmSources = new Map<string, string>();\n const pnpmWorkspaces = new Map<string, string[]>();\n for (const [file, content] of Object.entries(files)) {\n if (path.posix.basename(file) === \"pnpm-workspace.yaml\") {\n pnpmSources.set(path.posix.dirname(file), content);\n } else if (path.posix.basename(file) === \"package.json\")\n manifestSources.set(path.posix.dirname(file), content);\n }\n const assertWorkspaceOwner = (directory: string) => {\n if (pnpmSources.has(directory) && !manifestSources.has(directory))\n throw new Error(\n `consumer pnpm workspace requires an adjacent tracked package.json: ${path.posix.join(directory, \"pnpm-workspace.yaml\")}`,\n );\n };\n const candidates = new Set([\n ...manifestSources.keys(),\n ...pnpmSources.keys(),\n ]);\n const manifestAt = (directory: string) => {\n const cached = manifests.get(directory);\n if (cached) return cached;\n const source = manifestSources.get(directory);\n if (source === undefined) return undefined;\n const json: unknown = JSON.parse(source);\n if (!consumerRecord(json))\n throw new Error(`invalid package manifest: ${directory}/package.json`);\n manifests.set(directory, json);\n return json;\n };\n const patternsAt = (\n directory: string,\n manifest: Record<string, unknown> | undefined,\n ) => {\n const source = pnpmSources.get(directory);\n if (source !== undefined && !pnpmWorkspaces.has(directory)) {\n const file = `${directory}/pnpm-workspace.yaml`;\n const document = parseDocument(source, { uniqueKeys: true });\n if (document.errors.length)\n throw new Error(`invalid pnpm workspace: ${file}`);\n const json: unknown = document.toJS({ maxAliasCount: 100 });\n if (!consumerRecord(json))\n throw new Error(`invalid pnpm workspace: ${file}`);\n const patterns = json[\"packages\"] ?? [];\n if (\n !Array.isArray(patterns) ||\n !patterns.every((entry: unknown) => typeof entry === \"string\")\n )\n throw new Error(`invalid pnpm workspace packages: ${file}`);\n pnpmWorkspaces.set(\n directory,\n patterns.map((entry: string) => entry),\n );\n }\n return pnpmWorkspaces.get(directory) ?? workspacePatterns(manifest ?? {});\n };\n const roots = new Set([\".\"]);\n for (;;) {\n const before = roots.size;\n for (const directory of roots) {\n assertWorkspaceOwner(directory);\n const manifest = manifestAt(directory);\n const patterns = patternsAt(directory, manifest);\n for (const candidate of candidates) {\n const relative = path.posix.relative(directory, candidate);\n if (relative === \"\" || relative.startsWith(\"../\")) continue;\n const positives = patterns.filter(\n (pattern) => !pattern.startsWith(\"!\"),\n );\n const negatives = patterns\n .filter((pattern) => pattern.startsWith(\"!\"))\n .map((pattern) => pattern.slice(1));\n if (\n positives.some((pattern) => picomatch.isMatch(relative, pattern)) &&\n !negatives.some((pattern) => picomatch.isMatch(relative, pattern))\n )\n roots.add(candidate);\n }\n }\n if (before === roots.size) break;\n }\n const discovered = new Map<string, Record<string, unknown>>();\n for (const directory of roots) {\n for (let owner = directory; ; owner = path.posix.dirname(owner)) {\n assertWorkspaceOwner(owner);\n if (owner === \".\") break;\n }\n const manifest = manifestAt(directory);\n if (manifest) discovered.set(directory, manifest);\n }\n return discovered;\n};\n\nexport const discoverConsumerPackages = (files: Record<string, string>) => {\n const packages = new Map<string, ConsumerPackage>();\n for (const [directory, manifest] of discoverConsumerManifests(files)) {\n const name = manifest[\"name\"];\n if (typeof name !== \"string\" || name === \"\") continue;\n if (packages.has(name))\n throw new Error(`duplicate workspace package: ${name}`);\n packages.set(name, { directory, name, manifest });\n }\n return packages;\n};\n\nexport const consumerPublishedDependencyFields = [\n \"dependencies\",\n \"optionalDependencies\",\n \"peerDependencies\",\n] as const;\n\ntype ConsumerPackageClosureOptions = {\n selected: ConsumerPackage;\n packages: Map<string, ConsumerPackage>;\n files: Record<string, string>;\n};\nexport const consumerPackageClosure = ({\n selected,\n packages,\n files,\n}: ConsumerPackageClosureOptions) => {\n const closure = new Map<string, ConsumerPackage>();\n const visit = (pkg: ConsumerPackage) => {\n if (closure.has(pkg.name)) return;\n assertConsumerPublishableManifest(pkg);\n closure.set(pkg.name, pkg);\n for (const field of consumerPublishedDependencyFields) {\n const dependencies = pkg.manifest[field];\n if (!consumerRecord(dependencies)) continue;\n for (const [name, specifier] of Object.entries(dependencies)) {\n const local = packages.get(name);\n if (typeof specifier !== \"string\")\n throw new Error(`invalid package dependency: ${pkg.name} -> ${name}`);\n if (specifier.startsWith(\"catalog:\") && local !== undefined) {\n const resolved = resolveConsumerCatalog({\n directory: pkg.directory,\n name,\n specifier,\n files,\n });\n const version = local.manifest[\"version\"];\n if (\n resolved.startsWith(\"workspace:\") ||\n (typeof version === \"string\" &&\n validRange(resolved) !== null &&\n satisfies(version, resolved))\n )\n throw new Error(\n `catalog dependency ${name} resolves to workspace package ${local.name}; use workspace:`,\n );\n }\n if (/^workspace:(?:@[^/@]+\\/)?[^/@]+@/.test(specifier))\n throw new Error(\n `workspace alias specifiers are not supported by consumer-compat: ${name} -> ${specifier}; use the package name as the dependency key`,\n );\n if (/^(?:file:|link:)/.test(specifier))\n throw new Error(\n `published local dependencies must use workspace protocol: ${pkg.name} -> ${name}`,\n );\n if (\n local &&\n (specifier.startsWith(\"workspace:\") ||\n (typeof local.manifest[\"version\"] === \"string\" &&\n validRange(specifier) &&\n satisfies(local.manifest[\"version\"], specifier)))\n ) {\n if (local.manifest[\"private\"] === true)\n throw new Error(\n `published package depends on private workspace package: ${pkg.name} -> ${name}`,\n );\n visit(local);\n } else if (\n typeof specifier === \"string\" &&\n specifier.startsWith(\"workspace:\")\n )\n throw new Error(\n `unresolved workspace dependency: ${pkg.name} -> ${name}`,\n );\n }\n }\n };\n visit(selected);\n return closure;\n};\n\nexport const oldestPublishedConsumerVersion = (\n versions: readonly string[],\n range: string,\n) => {\n if (!validRange(range))\n throw new Error(`invalid consumer peer range: ${range}`);\n const candidates = versions\n .filter((version) => satisfies(version, range))\n .sort(compare);\n const version = candidates.at(0);\n if (!version)\n throw new Error(`no published consumer version satisfies ${range}`);\n return version;\n};\n","import { satisfies, validRange } from \"semver\";\n\ntype ConsumerNodeSupportOptions = { range: unknown; node: string };\n\nexport const consumerNodeSupportMatches = ({\n range,\n node,\n}: ConsumerNodeSupportOptions) =>\n range === undefined ||\n (typeof range === \"string\" &&\n range.trim() !== \"\" &&\n validRange(range) !== null &&\n satisfies(node, range));\n\ntype AssertConsumerNodeSupportOptions = {\n manifest: Record<string, unknown>;\n node: string;\n label: string;\n};\nexport const assertConsumerNodeSupport = ({\n manifest,\n node,\n label,\n}: AssertConsumerNodeSupportOptions) => {\n const engines = manifest[\"engines\"];\n const record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n if (\n (engines !== undefined && !record(engines)) ||\n !consumerNodeSupportMatches({\n range: record(engines) ? engines[\"node\"] : undefined,\n node,\n })\n )\n throw new Error(`${label} engines.node must support consumer Node ${node}`);\n};\n","import { valid } from \"semver\";\n\nimport { nodePolicyValid } from \"./toolchain-node\";\n\nexport const packagePinKeys = [\n \"oxlint\",\n \"oxlint-tsgolint\",\n \"@oxlint/plugins\",\n \"@stll/oxlint-plugin\",\n \"oxfmt\",\n \"lefthook\",\n] as const;\n\nexport const valkeyArchitectures = [\"amd64\", \"arm64\"] as const;\nexport const valkeyArtifactPackages = {\n server: \"valkey-server\",\n tools: \"valkey-tools\",\n} as const;\n\nconst record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst artifactRecord = (value: unknown, keys: readonly string[]) => {\n if (\n !record(value) ||\n Object.keys(value).some((key) => !keys.includes(key)) ||\n keys.some((key) => !Object.hasOwn(value, key))\n )\n throw new Error(\n \"valkeyArtifacts requires complete, closed artifact objects\",\n );\n return value;\n};\n\nconst parseValkeyArtifacts = (input: unknown, version: string) => {\n const architectures = artifactRecord(input, valkeyArchitectures);\n const line = version.split(\".\").slice(0, 2).join(\".\");\n const parseArchitecture = (\n architecture: (typeof valkeyArchitectures)[number],\n ) => {\n const packages = artifactRecord(\n architectures[architecture],\n Object.keys(valkeyArtifactPackages),\n );\n const parseArtifact = (kind: keyof typeof valkeyArtifactPackages) => {\n const artifact = artifactRecord(packages[kind], [\"url\", \"sha256\"]);\n const url = artifact[\"url\"];\n const sha256 = artifact[\"sha256\"];\n const expected = `https://download.valkey.io/packaging/valkey-${line}/deb/ubuntu2404/${architecture}/${valkeyArtifactPackages[kind]}_${version}-1.noble_${architecture}.deb`;\n if (typeof url !== \"string\" || url !== expected)\n throw new Error(\n \"valkeyArtifacts URL must select the exact official versioned Ubuntu artifact\",\n );\n if (typeof sha256 !== \"string\" || !/^[a-f0-9]{64}$/.test(sha256))\n throw new Error(\"valkeyArtifacts requires a lowercase SHA256 pin\");\n return { url, sha256 };\n };\n return {\n server: parseArtifact(\"server\"),\n tools: parseArtifact(\"tools\"),\n } satisfies Record<\n keyof typeof valkeyArtifactPackages,\n ReturnType<typeof parseArtifact>\n >;\n };\n return {\n amd64: parseArchitecture(\"amd64\"),\n arm64: parseArchitecture(\"arm64\"),\n } satisfies Record<\n (typeof valkeyArchitectures)[number],\n ReturnType<typeof parseArchitecture>\n >;\n};\n\n/** Reject unsupported or incomplete installed policies before inspecting a consumer. */\nexport const parseToolchainPolicy = (input: unknown) => {\n if (!record(input) || input[\"schemaVersion\"] !== 1)\n throw new Error(\"toolchain.json must use schemaVersion 1\");\n const string = (object: Record<string, unknown>, key: string) => {\n const value = object[key];\n if (typeof value !== \"string\" || value.trim() === \"\")\n throw new Error(`toolchain.json requires a nonempty ${key}`);\n return value;\n };\n const packages: Record<string, string> = {};\n for (const key of packagePinKeys) packages[key] = string(input, key);\n const bun = string(input, \"bun\");\n const typescript = string(input, \"typescript\");\n const node = string(input, \"node\");\n const consumerNode = string(input, \"consumerNode\");\n const consumerNpm = string(input, \"consumerNpm\");\n const consumerPnpm = string(input, \"consumerPnpm\");\n const consumerTypescript = string(input, \"consumerTypescript\");\n const python = string(input, \"python\");\n const postgres = string(input, \"postgres\");\n const valkey = string(input, \"valkey\");\n const rust = string(input, \"rust\");\n for (const [name, value] of Object.entries({\n ...packages,\n bun,\n typescript,\n consumerNpm,\n consumerPnpm,\n consumerTypescript,\n }))\n if (valid(value) !== value)\n throw new Error(`toolchain.json ${name} must be an exact release`);\n if (!/^[1-9]\\d*$/.test(postgres) || !Number.isSafeInteger(Number(postgres)))\n throw new Error(\"PostgreSQL must be a canonical positive major\");\n if (valid(valkey) !== valkey || !/^\\d+\\.\\d+\\.\\d+$/.test(valkey))\n throw new Error(\"Valkey must be an exact stable release\");\n const valkeyArtifacts = parseValkeyArtifacts(\n input[\"valkeyArtifacts\"],\n valkey,\n );\n if (!nodePolicyValid(node))\n throw new Error(\"Node must be a canonical major N.x series\");\n if (\n valid(consumerNode) !== consumerNode ||\n !consumerNode.startsWith(\"22.\") ||\n consumerNode.includes(\"-\") ||\n consumerNode.includes(\"+\")\n )\n throw new Error(\"consumerNode must be an exact stable Node 22 release\");\n if (!/^\\d+\\.\\d+(?:\\.\\d+)?$/.test(python))\n throw new Error(\"Python must be an exact minor or patch release\");\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(rust))\n throw new Error(\"Rust must be an exact stable release\");\n if (\n !consumerTypescript.startsWith(\"6.\") ||\n consumerTypescript.includes(\"-\") ||\n consumerTypescript.includes(\"+\")\n )\n throw new Error(\n \"consumerTypescript must be an exact stable TypeScript 6 release\",\n );\n const compatibility = input[\"typescript6Compatibility\"];\n if (!record(compatibility))\n throw new Error(\"missing TypeScript compatibility policy\");\n const version = string(compatibility, \"version\");\n const packageAlias = string(compatibility, \"packageAlias\");\n if (valid(version) !== version)\n throw new Error(\"TypeScript compatibility must be an exact release\");\n const layouts = input[\"typescriptInstallLayouts\"];\n if (!Array.isArray(layouts) || layouts.length === 0)\n throw new Error(\"missing TypeScript install layouts\");\n const typescriptInstallLayouts = layouts.map((layout: unknown) => {\n if (!record(layout)) throw new Error(\"invalid TypeScript install layout\");\n const compilerPackage = string(layout, \"compilerPackage\");\n const compilerSpecifier = string(layout, \"compilerSpecifier\");\n const typecheckCommand = string(layout, \"typecheckCommand\");\n switch (layout[\"type\"]) {\n case \"direct\":\n if (\n compilerSpecifier !== typescript ||\n compilerPackage !== \"typescript\"\n )\n throw new Error(\n \"direct TypeScript layout differs from shared version\",\n );\n return {\n type: \"direct\",\n compilerPackage,\n compilerSpecifier,\n typecheckCommand,\n } as const;\n case \"split-compatibility\": {\n const compatibilityPackage = string(layout, \"compatibilityPackage\");\n const compatibilitySpecifier = string(layout, \"compatibilitySpecifier\");\n if (\n compilerSpecifier !== `npm:typescript@${typescript}` ||\n compatibilitySpecifier !== version\n )\n throw new Error(\n \"split TypeScript layout differs from shared versions\",\n );\n return {\n type: \"split-compatibility\",\n compilerPackage,\n compilerSpecifier,\n compatibilityPackage,\n compatibilitySpecifier,\n typecheckCommand,\n } as const;\n }\n default:\n throw new Error(\"unsupported TypeScript install layout\");\n }\n });\n const actionsInput = input[\"actions\"];\n if (!record(actionsInput) || Object.keys(actionsInput).length === 0)\n throw new Error(\"missing approved actions\");\n const actions: Record<string, { sha: string; version: string }> = {};\n for (const [name, action] of Object.entries(actionsInput)) {\n if (!record(action)) throw new Error(`invalid action policy: ${name}`);\n const sha = string(action, \"sha\");\n const actionVersion = string(action, \"version\");\n if (!/^[a-f0-9]{40}$/.test(sha) || !/^v\\d+(?:\\.\\d+)*$/.test(actionVersion))\n throw new Error(`invalid action SHA/version: ${name}`);\n actions[name] = { sha, version: actionVersion };\n }\n const dependabotInput = input[\"dependabot\"];\n if (\n !record(dependabotInput) ||\n !record(dependabotInput[\"schedule\"]) ||\n !record(dependabotInput[\"cooldown\"]) ||\n !record(dependabotInput[\"groups\"])\n )\n throw new Error(\"missing Dependabot policy\");\n const scheduleInput = dependabotInput[\"schedule\"];\n const schedule = {\n interval: string(scheduleInput, \"interval\"),\n day: string(scheduleInput, \"day\"),\n time: string(scheduleInput, \"time\"),\n timezone: string(scheduleInput, \"timezone\"),\n };\n const defaultDays = dependabotInput[\"cooldown\"][\"defaultDays\"];\n if (\n typeof defaultDays !== \"number\" ||\n !Number.isInteger(defaultDays) ||\n defaultDays < 5\n )\n throw new Error(\"Dependabot cooldown must be at least five days\");\n const strings = (value: unknown): string[] => {\n if (\n !Array.isArray(value) ||\n !value.every((entry: unknown) => typeof entry === \"string\")\n )\n throw new Error(\"Dependabot group values must be string arrays\");\n return value;\n };\n const groups: Record<string, { patterns: string[]; updateTypes: string[] }> =\n {};\n for (const [name, group] of Object.entries(dependabotInput[\"groups\"])) {\n if (!record(group)) throw new Error(`invalid Dependabot group: ${name}`);\n groups[name] = {\n patterns: strings(group[\"patterns\"]),\n updateTypes: strings(group[\"updateTypes\"]),\n };\n }\n return {\n bun,\n typescript,\n node,\n postgres,\n valkey,\n valkeyArtifacts,\n consumerNode,\n consumerNpm,\n consumerPnpm,\n consumerTypescript,\n python,\n rust,\n packages,\n actions,\n typescriptInstallLayouts,\n typescript6Compatibility: { version, packageAlias },\n dependabot: {\n schedule,\n cooldown: { defaultDays },\n groups,\n ignoredPackages: [\n ...new Set([\n ...Object.keys(packages),\n ...typescriptInstallLayouts.flatMap((layout) =>\n layout.type === \"direct\"\n ? [layout.compilerPackage]\n : [layout.compilerPackage, layout.compatibilityPackage],\n ),\n packageAlias,\n \"bun-types\",\n ]),\n ],\n ignoredActions: Object.keys(actions),\n ignoredImages: [\"node\", \"python\", \"oven/bun\"],\n },\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toolchain-schema.mjs","names":[],"sources":["../src/toolchain-schema.ts"],"sourcesContent":["import { valid } from \"semver\";\n\nimport { nodePolicyValid } from \"./toolchain-node\";\n\nexport const packagePinKeys = [\n \"oxlint\",\n \"oxlint-tsgolint\",\n \"@oxlint/plugins\",\n \"@stll/oxlint-plugin\",\n \"oxfmt\",\n \"lefthook\",\n] as const;\n\nexport const valkeyArchitectures = [\"amd64\", \"arm64\"] as const;\nexport const valkeyArtifactPackages = {\n server: \"valkey-server\",\n tools: \"valkey-tools\",\n} as const;\n\nconst record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst artifactRecord = (value: unknown, keys: readonly string[]) => {\n if (\n !record(value) ||\n Object.keys(value).some((key) => !keys.includes(key)) ||\n keys.some((key) => !Object.hasOwn(value, key))\n )\n throw new Error(\n \"valkeyArtifacts requires complete, closed artifact objects\",\n );\n return value;\n};\n\nconst parseValkeyArtifacts = (input: unknown, version: string) => {\n const architectures = artifactRecord(input, valkeyArchitectures);\n const line = version.split(\".\").slice(0, 2).join(\".\");\n const parseArchitecture = (\n architecture: (typeof valkeyArchitectures)[number],\n ) => {\n const packages = artifactRecord(\n architectures[architecture],\n Object.keys(valkeyArtifactPackages),\n );\n const parseArtifact = (kind: keyof typeof valkeyArtifactPackages) => {\n const artifact = artifactRecord(packages[kind], [\"url\", \"sha256\"]);\n const url = artifact[\"url\"];\n const sha256 = artifact[\"sha256\"];\n const expected = `https://download.valkey.io/packaging/valkey-${line}/deb/ubuntu2404/${architecture}/${valkeyArtifactPackages[kind]}_${version}-1.noble_${architecture}.deb`;\n if (typeof url !== \"string\" || url !== expected)\n throw new Error(\n \"valkeyArtifacts URL must select the exact official versioned Ubuntu artifact\",\n );\n if (typeof sha256 !== \"string\" || !/^[a-f0-9]{64}$/.test(sha256))\n throw new Error(\"valkeyArtifacts requires a lowercase SHA256 pin\");\n return { url, sha256 };\n };\n return {\n server: parseArtifact(\"server\"),\n tools: parseArtifact(\"tools\"),\n } satisfies Record<\n keyof typeof valkeyArtifactPackages,\n ReturnType<typeof parseArtifact>\n >;\n };\n return {\n amd64: parseArchitecture(\"amd64\"),\n arm64: parseArchitecture(\"arm64\"),\n } satisfies Record<\n (typeof valkeyArchitectures)[number],\n ReturnType<typeof parseArchitecture>\n >;\n};\n\n/** Reject unsupported or incomplete installed policies before inspecting a consumer. */\nexport const parseToolchainPolicy = (input: unknown) => {\n if (!record(input) || input[\"schemaVersion\"] !== 1)\n throw new Error(\"toolchain.json must use schemaVersion 1\");\n const string = (object: Record<string, unknown>, key: string) => {\n const value = object[key];\n if (typeof value !== \"string\" || value.trim() === \"\")\n throw new Error(`toolchain.json requires a nonempty ${key}`);\n return value;\n };\n const packages: Record<string, string> = {};\n for (const key of packagePinKeys) packages[key] = string(input, key);\n const bun = string(input, \"bun\");\n const typescript = string(input, \"typescript\");\n const node = string(input, \"node\");\n const consumerNode = string(input, \"consumerNode\");\n const consumerNpm = string(input, \"consumerNpm\");\n const consumerPnpm = string(input, \"consumerPnpm\");\n const consumerTypescript = string(input, \"consumerTypescript\");\n const python = string(input, \"python\");\n const postgres = string(input, \"postgres\");\n const valkey = string(input, \"valkey\");\n const rust = string(input, \"rust\");\n for (const [name, value] of Object.entries({\n ...packages,\n bun,\n typescript,\n consumerNpm,\n consumerPnpm,\n consumerTypescript,\n }))\n if (valid(value) !== value)\n throw new Error(`toolchain.json ${name} must be an exact release`);\n if (!/^[1-9]\\d*$/.test(postgres) || !Number.isSafeInteger(Number(postgres)))\n throw new Error(\"PostgreSQL must be a canonical positive major\");\n if (valid(valkey) !== valkey || !/^\\d+\\.\\d+\\.\\d+$/.test(valkey))\n throw new Error(\"Valkey must be an exact stable release\");\n const valkeyArtifacts = parseValkeyArtifacts(\n input[\"valkeyArtifacts\"],\n valkey,\n );\n if (!nodePolicyValid(node))\n throw new Error(\"Node must be a canonical major N.x series\");\n if (\n valid(consumerNode) !== consumerNode ||\n !consumerNode.startsWith(\"22.\") ||\n consumerNode.includes(\"-\") ||\n consumerNode.includes(\"+\")\n )\n throw new Error(\"consumerNode must be an exact stable Node 22 release\");\n if (!/^\\d+\\.\\d+(?:\\.\\d+)?$/.test(python))\n throw new Error(\"Python must be an exact minor or patch release\");\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(rust))\n throw new Error(\"Rust must be an exact stable release\");\n if (\n !consumerTypescript.startsWith(\"6.\") ||\n consumerTypescript.includes(\"-\") ||\n consumerTypescript.includes(\"+\")\n )\n throw new Error(\n \"consumerTypescript must be an exact stable TypeScript 6 release\",\n );\n const compatibility = input[\"typescript6Compatibility\"];\n if (!record(compatibility))\n throw new Error(\"missing TypeScript compatibility policy\");\n const version = string(compatibility, \"version\");\n const packageAlias = string(compatibility, \"packageAlias\");\n if (valid(version) !== version)\n throw new Error(\"TypeScript compatibility must be an exact release\");\n const layouts = input[\"typescriptInstallLayouts\"];\n if (!Array.isArray(layouts) || layouts.length === 0)\n throw new Error(\"missing TypeScript install layouts\");\n const typescriptInstallLayouts = layouts.map((layout: unknown) => {\n if (!record(layout)) throw new Error(\"invalid TypeScript install layout\");\n const compilerPackage = string(layout, \"compilerPackage\");\n const compilerSpecifier = string(layout, \"compilerSpecifier\");\n const typecheckCommand = string(layout, \"typecheckCommand\");\n switch (layout[\"type\"]) {\n case \"direct\":\n if (\n compilerSpecifier !== typescript ||\n compilerPackage !== \"typescript\"\n )\n throw new Error(\n \"direct TypeScript layout differs from shared version\",\n );\n return {\n type: \"direct\",\n compilerPackage,\n compilerSpecifier,\n typecheckCommand,\n } as const;\n case \"split-compatibility\": {\n const compatibilityPackage = string(layout, \"compatibilityPackage\");\n const compatibilitySpecifier = string(layout, \"compatibilitySpecifier\");\n if (\n compilerSpecifier !== `npm:typescript@${typescript}` ||\n compatibilitySpecifier !== version\n )\n throw new Error(\n \"split TypeScript layout differs from shared versions\",\n );\n return {\n type: \"split-compatibility\",\n compilerPackage,\n compilerSpecifier,\n compatibilityPackage,\n compatibilitySpecifier,\n typecheckCommand,\n } as const;\n }\n default:\n throw new Error(\"unsupported TypeScript install layout\");\n }\n });\n const actionsInput = input[\"actions\"];\n if (!record(actionsInput) || Object.keys(actionsInput).length === 0)\n throw new Error(\"missing approved actions\");\n const actions: Record<string, { sha: string; version: string }> = {};\n for (const [name, action] of Object.entries(actionsInput)) {\n if (!record(action)) throw new Error(`invalid action policy: ${name}`);\n const sha = string(action, \"sha\");\n const actionVersion = string(action, \"version\");\n if (!/^[a-f0-9]{40}$/.test(sha) || !/^v\\d+(?:\\.\\d+)*$/.test(actionVersion))\n throw new Error(`invalid action SHA/version: ${name}`);\n actions[name] = { sha, version: actionVersion };\n }\n const dependabotInput = input[\"dependabot\"];\n if (\n !record(dependabotInput) ||\n !record(dependabotInput[\"schedule\"]) ||\n !record(dependabotInput[\"cooldown\"]) ||\n !record(dependabotInput[\"groups\"])\n )\n throw new Error(\"missing Dependabot policy\");\n const scheduleInput = dependabotInput[\"schedule\"];\n const schedule = {\n interval: string(scheduleInput, \"interval\"),\n day: string(scheduleInput, \"day\"),\n time: string(scheduleInput, \"time\"),\n timezone: string(scheduleInput, \"timezone\"),\n };\n const defaultDays = dependabotInput[\"cooldown\"][\"defaultDays\"];\n if (\n typeof defaultDays !== \"number\" ||\n !Number.isInteger(defaultDays) ||\n defaultDays < 5\n )\n throw new Error(\"Dependabot cooldown must be at least five days\");\n const strings = (value: unknown): string[] => {\n if (\n !Array.isArray(value) ||\n !value.every((entry: unknown) => typeof entry === \"string\")\n )\n throw new Error(\"Dependabot group values must be string arrays\");\n return value;\n };\n const groups: Record<string, { patterns: string[]; updateTypes: string[] }> =\n {};\n for (const [name, group] of Object.entries(dependabotInput[\"groups\"])) {\n if (!record(group)) throw new Error(`invalid Dependabot group: ${name}`);\n groups[name] = {\n patterns: strings(group[\"patterns\"]),\n updateTypes: strings(group[\"updateTypes\"]),\n };\n }\n return {\n bun,\n typescript,\n node,\n postgres,\n valkey,\n valkeyArtifacts,\n consumerNode,\n consumerNpm,\n consumerPnpm,\n consumerTypescript,\n python,\n rust,\n packages,\n actions,\n typescriptInstallLayouts,\n typescript6Compatibility: { version, packageAlias },\n dependabot: {\n schedule,\n cooldown: { defaultDays },\n groups,\n ignoredPackages: [\n ...new Set([\n ...Object.keys(packages),\n ...typescriptInstallLayouts.flatMap((layout) =>\n layout.type === \"direct\"\n ? [layout.compilerPackage]\n : [layout.compilerPackage, layout.compatibilityPackage],\n ),\n packageAlias,\n \"bun-types\",\n ]),\n ],\n ignoredActions: Object.keys(actions),\n ignoredImages: [\"node\", \"python\", \"oven/bun\"],\n },\n };\n};\n"],"mappings":"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"}
|
|
@@ -3,8 +3,8 @@ let node_child_process = require("node:child_process");
|
|
|
3
3
|
let node_path = require("node:path");
|
|
4
4
|
let node_util = require("node:util");
|
|
5
5
|
let node_os = require("node:os");
|
|
6
|
-
let node_fs_promises = require("node:fs/promises");
|
|
7
6
|
let node_module = require("node:module");
|
|
7
|
+
let node_fs_promises = require("node:fs/promises");
|
|
8
8
|
let node_perf_hooks = require("node:perf_hooks");
|
|
9
9
|
//#region src/typecheck-parity.ts
|
|
10
10
|
const fixtures = [
|
|
@@ -120,7 +120,7 @@ const runTypecheckProbe = async ({ repo, project, seedDirectory, command, output
|
|
|
120
120
|
}
|
|
121
121
|
const seeded = await execute();
|
|
122
122
|
if (seeded.status === null || seeded.status === 0) throw new Error(`typecheck probe expected the seeded command to fail: ${seedLocation}`);
|
|
123
|
-
if (!require_typecheck_parity.diagnosticSet(seeded.output,
|
|
123
|
+
if (![.../* @__PURE__ */ new Set([root, (0, node_path.dirname)(config)])].some((origin) => require_typecheck_parity.diagnosticSet(seeded.output, origin).includes(`${(0, node_path.relative)(origin, seed).replaceAll("\\", "/")}:1:2322`))) throw new Error(`typecheck probe expected TS2322 attributed to ${seedLocation}; the declared project may exclude the seed`);
|
|
124
124
|
await removeSeed();
|
|
125
125
|
const clean = await execute();
|
|
126
126
|
if (clean.status !== 0) throw new Error(`typecheck probe clean command failed with status ${clean.status ?? "unknown"}: ${project}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typecheck-probe-cli.cjs","names":["spawn","path","realpath","resolve","stat","dirname","isAbsolute","join","randomUUID","relative","unlink","open","diagnosticSet"],"sources":["../src/typecheck-probe.ts","../src/typecheck-probe-args.ts","../src/typecheck-probe-cli.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { open, realpath, stat, unlink } from \"node:fs/promises\";\nimport path, { dirname, isAbsolute, join, relative, resolve } from \"node:path\";\n\nimport { diagnosticSet } from \"./typecheck-parity\";\n\ntype ProbeCommandOptions = {\n command: readonly string[];\n cwd: string;\n signal: AbortSignal;\n};\ntype ProbeCommandResult = { status: number | null; output: string };\n\nconst runProbeCommand = ({ command, cwd, signal }: ProbeCommandOptions) =>\n new Promise<ProbeCommandResult>((done, reject) => {\n const executable = command.at(0);\n if (executable === undefined) {\n reject(new Error(\"typecheck probe command is empty\"));\n return;\n }\n const child = spawn(executable, command.slice(1), {\n cwd,\n signal,\n shell: false,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n let output = \"\";\n child.stdout.on(\"data\", (chunk: Buffer) => {\n output += chunk.toString();\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n output += chunk.toString();\n });\n child.once(\"error\", reject);\n child.once(\"close\", (status) => done({ status, output }));\n });\n\ntype ProbePathContainmentOptions = {\n root: string;\n candidate: string;\n paths?: Pick<typeof path, \"relative\" | \"isAbsolute\" | \"sep\">;\n};\n\nexport const insideProbePath = ({\n root,\n candidate,\n paths = path,\n}: ProbePathContainmentOptions) => {\n const location = paths.relative(root, candidate);\n return (\n location !== \"..\" &&\n !location.startsWith(\"..\" + paths.sep) &&\n !paths.isAbsolute(location)\n );\n};\n\ntype RunTypecheckProbeOptions = {\n repo: string;\n project: string;\n seedDirectory?: string | undefined;\n command: readonly string[];\n output?: (text: string) => void;\n run?: (options: ProbeCommandOptions) => Promise<ProbeCommandResult>;\n};\n\nexport const runTypecheckProbe = async ({\n repo,\n project,\n seedDirectory,\n command,\n output,\n run = runProbeCommand,\n}: RunTypecheckProbeOptions) => {\n const executable = command.at(0);\n if (\n executable === undefined ||\n executable === \"\" ||\n command.some((argument) => argument.includes(\"\\0\"))\n )\n throw new Error(\n \"typecheck probe requires a nonempty command argv without NUL bytes\",\n );\n if (project === \"\")\n throw new Error(\"typecheck probe requires an explicit project file\");\n const root = await realpath(repo);\n const requested = resolve(root, project);\n if (!insideProbePath({ root, candidate: requested }))\n throw new Error(\n `typecheck probe project is outside the repository: ${project}`,\n );\n const config = await realpath(requested);\n if (!insideProbePath({ root, candidate: config }))\n throw new Error(\n `typecheck probe project resolves outside the repository: ${project}`,\n );\n if (!(await stat(config)).isFile())\n throw new Error(`typecheck probe project must be a file: ${project}`);\n let seedParent = dirname(config);\n if (seedDirectory !== undefined) {\n if (seedDirectory === \"\" || isAbsolute(seedDirectory))\n throw new Error(\n \"typecheck probe seed directory must be repository-relative\",\n );\n const requestedSeedParent = resolve(root, seedDirectory);\n if (!insideProbePath({ root, candidate: requestedSeedParent }))\n throw new Error(\n `typecheck probe seed directory is outside the repository: ${seedDirectory}`,\n );\n seedParent = await realpath(requestedSeedParent);\n if (\n !insideProbePath({ root, candidate: seedParent }) ||\n !insideProbePath({ root: dirname(config), candidate: seedParent })\n )\n throw new Error(\n `typecheck probe seed directory must be inside the declared project: ${seedDirectory}`,\n );\n if (!(await stat(seedParent)).isDirectory())\n throw new Error(\n `typecheck probe seed directory must be a directory: ${seedDirectory}`,\n );\n }\n const seed = join(seedParent, `stll-typecheck-probe-${randomUUID()}.ts`);\n const seedLocation = relative(root, seed).replaceAll(\"\\\\\", \"/\");\n const controller = new AbortController();\n const interrupt = (signal: string) =>\n controller.abort(new Error(`typecheck probe interrupted by ${signal}`));\n const onInterrupt = () => interrupt(\"SIGINT\");\n const onTerminate = () => interrupt(\"SIGTERM\");\n process.on(\"SIGINT\", onInterrupt);\n process.on(\"SIGTERM\", onTerminate);\n let created = false;\n const removeSeed = async () => {\n if (!created) return;\n await unlink(seed);\n created = false;\n };\n const execute = async () => {\n controller.signal.throwIfAborted();\n let onAbort: (() => void) | undefined;\n const aborted = new Promise<never>((_done, reject) => {\n onAbort = () => reject(controller.signal.reason);\n controller.signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n try {\n const result = await Promise.race([\n run({ command, cwd: root, signal: controller.signal }),\n aborted,\n ]);\n controller.signal.throwIfAborted();\n output?.(result.output);\n return result;\n } finally {\n if (onAbort !== undefined)\n controller.signal.removeEventListener(\"abort\", onAbort);\n }\n };\n try {\n controller.signal.throwIfAborted();\n const file = await open(seed, \"wx\", 0o600);\n created = true;\n try {\n await file.writeFile('export const typecheckProbe: number = \"wrong\";\\n');\n } finally {\n await file.close();\n }\n const seeded = await execute();\n if (seeded.status === null || seeded.status === 0)\n throw new Error(\n `typecheck probe expected the seeded command to fail: ${seedLocation}`,\n );\n if (!diagnosticSet(seeded.output, root).includes(`${seedLocation}:1:2322`))\n throw new Error(\n `typecheck probe expected TS2322 attributed to ${seedLocation}; the declared project may exclude the seed`,\n );\n await removeSeed();\n const clean = await execute();\n if (clean.status !== 0)\n throw new Error(\n `typecheck probe clean command failed with status ${clean.status ?? \"unknown\"}: ${project}`,\n );\n } finally {\n try {\n await removeSeed();\n } finally {\n process.removeListener(\"SIGINT\", onInterrupt);\n process.removeListener(\"SIGTERM\", onTerminate);\n }\n }\n};\n","export const probeUsage =\n \"Usage: stll-typecheck-probe --project <tsconfig> [--seed-dir <directory>] -- <command> [args...]\\n stll-typecheck-probe --help\";\n\nexport const parseProbeArguments = (args: readonly string[]) => {\n if (args.length === 1 && args.at(0) === \"--help\")\n return { mode: \"help\" } as const;\n const project = args.at(1);\n const seedDirectory = args.at(2) === \"--seed-dir\" ? args.at(3) : undefined;\n const separator = seedDirectory === undefined ? 2 : 4;\n const command = args.slice(separator + 1);\n if (\n args.at(0) !== \"--project\" ||\n project === undefined ||\n project.trim() === \"\" ||\n project.startsWith(\"-\") ||\n args.at(separator) !== \"--\" ||\n (seedDirectory !== undefined &&\n (seedDirectory.trim() === \"\" || seedDirectory.startsWith(\"-\"))) ||\n command.length === 0 ||\n command.some((value) => value.trim() === \"\")\n )\n throw new Error(probeUsage);\n return {\n mode: \"probe\",\n project,\n command,\n ...(seedDirectory === undefined ? {} : { seedDirectory }),\n } as const;\n};\n","#!/usr/bin/env node\nimport { runTypecheckProbe } from \"./typecheck-probe\";\nimport { parseProbeArguments, probeUsage } from \"./typecheck-probe-args\";\n\nconst main = async () => {\n const args = parseProbeArguments(process.argv.slice(2));\n if (args.mode === \"help\") {\n process.stdout.write(`${probeUsage}\\n`);\n return;\n }\n await runTypecheckProbe({\n repo: process.cwd(),\n project: args.project,\n command: args.command,\n seedDirectory: args.seedDirectory,\n output: (text) => process.stdout.write(text),\n });\n process.stdout.write(\n \"typecheck probe passed: seeded TS2322 detected and clean typecheck passed\\n\",\n );\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `typecheck-probe: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"typecheck-probe-cli.cjs","names":["spawn","path","realpath","resolve","stat","dirname","isAbsolute","join","randomUUID","relative","unlink","open","diagnosticSet"],"sources":["../src/typecheck-probe.ts","../src/typecheck-probe-args.ts","../src/typecheck-probe-cli.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { open, realpath, stat, unlink } from \"node:fs/promises\";\nimport path, { dirname, isAbsolute, join, relative, resolve } from \"node:path\";\n\nimport { diagnosticSet } from \"./typecheck-parity\";\n\ntype ProbeCommandOptions = {\n command: readonly string[];\n cwd: string;\n signal: AbortSignal;\n};\ntype ProbeCommandResult = { status: number | null; output: string };\n\nconst runProbeCommand = ({ command, cwd, signal }: ProbeCommandOptions) =>\n new Promise<ProbeCommandResult>((done, reject) => {\n const executable = command.at(0);\n if (executable === undefined) {\n reject(new Error(\"typecheck probe command is empty\"));\n return;\n }\n const child = spawn(executable, command.slice(1), {\n cwd,\n signal,\n shell: false,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n let output = \"\";\n child.stdout.on(\"data\", (chunk: Buffer) => {\n output += chunk.toString();\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n output += chunk.toString();\n });\n child.once(\"error\", reject);\n child.once(\"close\", (status) => done({ status, output }));\n });\n\ntype ProbePathContainmentOptions = {\n root: string;\n candidate: string;\n paths?: Pick<typeof path, \"relative\" | \"isAbsolute\" | \"sep\">;\n};\n\nexport const insideProbePath = ({\n root,\n candidate,\n paths = path,\n}: ProbePathContainmentOptions) => {\n const location = paths.relative(root, candidate);\n return (\n location !== \"..\" &&\n !location.startsWith(\"..\" + paths.sep) &&\n !paths.isAbsolute(location)\n );\n};\n\ntype RunTypecheckProbeOptions = {\n repo: string;\n project: string;\n seedDirectory?: string | undefined;\n command: readonly string[];\n output?: (text: string) => void;\n run?: (options: ProbeCommandOptions) => Promise<ProbeCommandResult>;\n};\n\nexport const runTypecheckProbe = async ({\n repo,\n project,\n seedDirectory,\n command,\n output,\n run = runProbeCommand,\n}: RunTypecheckProbeOptions) => {\n const executable = command.at(0);\n if (\n executable === undefined ||\n executable === \"\" ||\n command.some((argument) => argument.includes(\"\\0\"))\n )\n throw new Error(\n \"typecheck probe requires a nonempty command argv without NUL bytes\",\n );\n if (project === \"\")\n throw new Error(\"typecheck probe requires an explicit project file\");\n const root = await realpath(repo);\n const requested = resolve(root, project);\n if (!insideProbePath({ root, candidate: requested }))\n throw new Error(\n `typecheck probe project is outside the repository: ${project}`,\n );\n const config = await realpath(requested);\n if (!insideProbePath({ root, candidate: config }))\n throw new Error(\n `typecheck probe project resolves outside the repository: ${project}`,\n );\n if (!(await stat(config)).isFile())\n throw new Error(`typecheck probe project must be a file: ${project}`);\n let seedParent = dirname(config);\n if (seedDirectory !== undefined) {\n if (seedDirectory === \"\" || isAbsolute(seedDirectory))\n throw new Error(\n \"typecheck probe seed directory must be repository-relative\",\n );\n const requestedSeedParent = resolve(root, seedDirectory);\n if (!insideProbePath({ root, candidate: requestedSeedParent }))\n throw new Error(\n `typecheck probe seed directory is outside the repository: ${seedDirectory}`,\n );\n seedParent = await realpath(requestedSeedParent);\n if (\n !insideProbePath({ root, candidate: seedParent }) ||\n !insideProbePath({ root: dirname(config), candidate: seedParent })\n )\n throw new Error(\n `typecheck probe seed directory must be inside the declared project: ${seedDirectory}`,\n );\n if (!(await stat(seedParent)).isDirectory())\n throw new Error(\n `typecheck probe seed directory must be a directory: ${seedDirectory}`,\n );\n }\n const seed = join(seedParent, `stll-typecheck-probe-${randomUUID()}.ts`);\n const seedLocation = relative(root, seed).replaceAll(\"\\\\\", \"/\");\n const controller = new AbortController();\n const interrupt = (signal: string) =>\n controller.abort(new Error(`typecheck probe interrupted by ${signal}`));\n const onInterrupt = () => interrupt(\"SIGINT\");\n const onTerminate = () => interrupt(\"SIGTERM\");\n process.on(\"SIGINT\", onInterrupt);\n process.on(\"SIGTERM\", onTerminate);\n let created = false;\n const removeSeed = async () => {\n if (!created) return;\n await unlink(seed);\n created = false;\n };\n const execute = async () => {\n controller.signal.throwIfAborted();\n let onAbort: (() => void) | undefined;\n const aborted = new Promise<never>((_done, reject) => {\n onAbort = () => reject(controller.signal.reason);\n controller.signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n try {\n const result = await Promise.race([\n run({ command, cwd: root, signal: controller.signal }),\n aborted,\n ]);\n controller.signal.throwIfAborted();\n output?.(result.output);\n return result;\n } finally {\n if (onAbort !== undefined)\n controller.signal.removeEventListener(\"abort\", onAbort);\n }\n };\n try {\n controller.signal.throwIfAborted();\n const file = await open(seed, \"wx\", 0o600);\n created = true;\n try {\n await file.writeFile('export const typecheckProbe: number = \"wrong\";\\n');\n } finally {\n await file.close();\n }\n const seeded = await execute();\n if (seeded.status === null || seeded.status === 0)\n throw new Error(\n `typecheck probe expected the seeded command to fail: ${seedLocation}`,\n );\n // Workspace runners may report compiler paths from the declared project.\n // Only the exact owned seed under either known command origin is accepted.\n const origins = new Set([root, dirname(config)]);\n const attributed = [...origins].some((origin) =>\n diagnosticSet(seeded.output, origin).includes(\n `${relative(origin, seed).replaceAll(\"\\\\\", \"/\")}:1:2322`,\n ),\n );\n if (!attributed)\n throw new Error(\n `typecheck probe expected TS2322 attributed to ${seedLocation}; the declared project may exclude the seed`,\n );\n await removeSeed();\n const clean = await execute();\n if (clean.status !== 0)\n throw new Error(\n `typecheck probe clean command failed with status ${clean.status ?? \"unknown\"}: ${project}`,\n );\n } finally {\n try {\n await removeSeed();\n } finally {\n process.removeListener(\"SIGINT\", onInterrupt);\n process.removeListener(\"SIGTERM\", onTerminate);\n }\n }\n};\n","export const probeUsage =\n \"Usage: stll-typecheck-probe --project <tsconfig> [--seed-dir <directory>] -- <command> [args...]\\n stll-typecheck-probe --help\";\n\nexport const parseProbeArguments = (args: readonly string[]) => {\n if (args.length === 1 && args.at(0) === \"--help\")\n return { mode: \"help\" } as const;\n const project = args.at(1);\n const seedDirectory = args.at(2) === \"--seed-dir\" ? args.at(3) : undefined;\n const separator = seedDirectory === undefined ? 2 : 4;\n const command = args.slice(separator + 1);\n if (\n args.at(0) !== \"--project\" ||\n project === undefined ||\n project.trim() === \"\" ||\n project.startsWith(\"-\") ||\n args.at(separator) !== \"--\" ||\n (seedDirectory !== undefined &&\n (seedDirectory.trim() === \"\" || seedDirectory.startsWith(\"-\"))) ||\n command.length === 0 ||\n command.some((value) => value.trim() === \"\")\n )\n throw new Error(probeUsage);\n return {\n mode: \"probe\",\n project,\n command,\n ...(seedDirectory === undefined ? {} : { seedDirectory }),\n } as const;\n};\n","#!/usr/bin/env node\nimport { runTypecheckProbe } from \"./typecheck-probe\";\nimport { parseProbeArguments, probeUsage } from \"./typecheck-probe-args\";\n\nconst main = async () => {\n const args = parseProbeArguments(process.argv.slice(2));\n if (args.mode === \"help\") {\n process.stdout.write(`${probeUsage}\\n`);\n return;\n }\n await runTypecheckProbe({\n repo: process.cwd(),\n project: args.project,\n command: args.command,\n seedDirectory: args.seedDirectory,\n output: (text) => process.stdout.write(text),\n });\n process.stdout.write(\n \"typecheck probe passed: seeded TS2322 detected and clean typecheck passed\\n\",\n );\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `typecheck-probe: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":"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"}
|
|
@@ -117,7 +117,7 @@ const runTypecheckProbe = async ({ repo, project, seedDirectory, command, output
|
|
|
117
117
|
}
|
|
118
118
|
const seeded = await execute();
|
|
119
119
|
if (seeded.status === null || seeded.status === 0) throw new Error(`typecheck probe expected the seeded command to fail: ${seedLocation}`);
|
|
120
|
-
if (!diagnosticSet(seeded.output,
|
|
120
|
+
if (![.../* @__PURE__ */ new Set([root, dirname(config)])].some((origin) => diagnosticSet(seeded.output, origin).includes(`${relative(origin, seed).replaceAll("\\", "/")}:1:2322`))) throw new Error(`typecheck probe expected TS2322 attributed to ${seedLocation}; the declared project may exclude the seed`);
|
|
121
121
|
await removeSeed();
|
|
122
122
|
const clean = await execute();
|
|
123
123
|
if (clean.status !== 0) throw new Error(`typecheck probe clean command failed with status ${clean.status ?? "unknown"}: ${project}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typecheck-probe-cli.mjs","names":[],"sources":["../src/typecheck-probe.ts","../src/typecheck-probe-args.ts","../src/typecheck-probe-cli.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { open, realpath, stat, unlink } from \"node:fs/promises\";\nimport path, { dirname, isAbsolute, join, relative, resolve } from \"node:path\";\n\nimport { diagnosticSet } from \"./typecheck-parity\";\n\ntype ProbeCommandOptions = {\n command: readonly string[];\n cwd: string;\n signal: AbortSignal;\n};\ntype ProbeCommandResult = { status: number | null; output: string };\n\nconst runProbeCommand = ({ command, cwd, signal }: ProbeCommandOptions) =>\n new Promise<ProbeCommandResult>((done, reject) => {\n const executable = command.at(0);\n if (executable === undefined) {\n reject(new Error(\"typecheck probe command is empty\"));\n return;\n }\n const child = spawn(executable, command.slice(1), {\n cwd,\n signal,\n shell: false,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n let output = \"\";\n child.stdout.on(\"data\", (chunk: Buffer) => {\n output += chunk.toString();\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n output += chunk.toString();\n });\n child.once(\"error\", reject);\n child.once(\"close\", (status) => done({ status, output }));\n });\n\ntype ProbePathContainmentOptions = {\n root: string;\n candidate: string;\n paths?: Pick<typeof path, \"relative\" | \"isAbsolute\" | \"sep\">;\n};\n\nexport const insideProbePath = ({\n root,\n candidate,\n paths = path,\n}: ProbePathContainmentOptions) => {\n const location = paths.relative(root, candidate);\n return (\n location !== \"..\" &&\n !location.startsWith(\"..\" + paths.sep) &&\n !paths.isAbsolute(location)\n );\n};\n\ntype RunTypecheckProbeOptions = {\n repo: string;\n project: string;\n seedDirectory?: string | undefined;\n command: readonly string[];\n output?: (text: string) => void;\n run?: (options: ProbeCommandOptions) => Promise<ProbeCommandResult>;\n};\n\nexport const runTypecheckProbe = async ({\n repo,\n project,\n seedDirectory,\n command,\n output,\n run = runProbeCommand,\n}: RunTypecheckProbeOptions) => {\n const executable = command.at(0);\n if (\n executable === undefined ||\n executable === \"\" ||\n command.some((argument) => argument.includes(\"\\0\"))\n )\n throw new Error(\n \"typecheck probe requires a nonempty command argv without NUL bytes\",\n );\n if (project === \"\")\n throw new Error(\"typecheck probe requires an explicit project file\");\n const root = await realpath(repo);\n const requested = resolve(root, project);\n if (!insideProbePath({ root, candidate: requested }))\n throw new Error(\n `typecheck probe project is outside the repository: ${project}`,\n );\n const config = await realpath(requested);\n if (!insideProbePath({ root, candidate: config }))\n throw new Error(\n `typecheck probe project resolves outside the repository: ${project}`,\n );\n if (!(await stat(config)).isFile())\n throw new Error(`typecheck probe project must be a file: ${project}`);\n let seedParent = dirname(config);\n if (seedDirectory !== undefined) {\n if (seedDirectory === \"\" || isAbsolute(seedDirectory))\n throw new Error(\n \"typecheck probe seed directory must be repository-relative\",\n );\n const requestedSeedParent = resolve(root, seedDirectory);\n if (!insideProbePath({ root, candidate: requestedSeedParent }))\n throw new Error(\n `typecheck probe seed directory is outside the repository: ${seedDirectory}`,\n );\n seedParent = await realpath(requestedSeedParent);\n if (\n !insideProbePath({ root, candidate: seedParent }) ||\n !insideProbePath({ root: dirname(config), candidate: seedParent })\n )\n throw new Error(\n `typecheck probe seed directory must be inside the declared project: ${seedDirectory}`,\n );\n if (!(await stat(seedParent)).isDirectory())\n throw new Error(\n `typecheck probe seed directory must be a directory: ${seedDirectory}`,\n );\n }\n const seed = join(seedParent, `stll-typecheck-probe-${randomUUID()}.ts`);\n const seedLocation = relative(root, seed).replaceAll(\"\\\\\", \"/\");\n const controller = new AbortController();\n const interrupt = (signal: string) =>\n controller.abort(new Error(`typecheck probe interrupted by ${signal}`));\n const onInterrupt = () => interrupt(\"SIGINT\");\n const onTerminate = () => interrupt(\"SIGTERM\");\n process.on(\"SIGINT\", onInterrupt);\n process.on(\"SIGTERM\", onTerminate);\n let created = false;\n const removeSeed = async () => {\n if (!created) return;\n await unlink(seed);\n created = false;\n };\n const execute = async () => {\n controller.signal.throwIfAborted();\n let onAbort: (() => void) | undefined;\n const aborted = new Promise<never>((_done, reject) => {\n onAbort = () => reject(controller.signal.reason);\n controller.signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n try {\n const result = await Promise.race([\n run({ command, cwd: root, signal: controller.signal }),\n aborted,\n ]);\n controller.signal.throwIfAborted();\n output?.(result.output);\n return result;\n } finally {\n if (onAbort !== undefined)\n controller.signal.removeEventListener(\"abort\", onAbort);\n }\n };\n try {\n controller.signal.throwIfAborted();\n const file = await open(seed, \"wx\", 0o600);\n created = true;\n try {\n await file.writeFile('export const typecheckProbe: number = \"wrong\";\\n');\n } finally {\n await file.close();\n }\n const seeded = await execute();\n if (seeded.status === null || seeded.status === 0)\n throw new Error(\n `typecheck probe expected the seeded command to fail: ${seedLocation}`,\n );\n if (!diagnosticSet(seeded.output, root).includes(`${seedLocation}:1:2322`))\n throw new Error(\n `typecheck probe expected TS2322 attributed to ${seedLocation}; the declared project may exclude the seed`,\n );\n await removeSeed();\n const clean = await execute();\n if (clean.status !== 0)\n throw new Error(\n `typecheck probe clean command failed with status ${clean.status ?? \"unknown\"}: ${project}`,\n );\n } finally {\n try {\n await removeSeed();\n } finally {\n process.removeListener(\"SIGINT\", onInterrupt);\n process.removeListener(\"SIGTERM\", onTerminate);\n }\n }\n};\n","export const probeUsage =\n \"Usage: stll-typecheck-probe --project <tsconfig> [--seed-dir <directory>] -- <command> [args...]\\n stll-typecheck-probe --help\";\n\nexport const parseProbeArguments = (args: readonly string[]) => {\n if (args.length === 1 && args.at(0) === \"--help\")\n return { mode: \"help\" } as const;\n const project = args.at(1);\n const seedDirectory = args.at(2) === \"--seed-dir\" ? args.at(3) : undefined;\n const separator = seedDirectory === undefined ? 2 : 4;\n const command = args.slice(separator + 1);\n if (\n args.at(0) !== \"--project\" ||\n project === undefined ||\n project.trim() === \"\" ||\n project.startsWith(\"-\") ||\n args.at(separator) !== \"--\" ||\n (seedDirectory !== undefined &&\n (seedDirectory.trim() === \"\" || seedDirectory.startsWith(\"-\"))) ||\n command.length === 0 ||\n command.some((value) => value.trim() === \"\")\n )\n throw new Error(probeUsage);\n return {\n mode: \"probe\",\n project,\n command,\n ...(seedDirectory === undefined ? {} : { seedDirectory }),\n } as const;\n};\n","#!/usr/bin/env node\nimport { runTypecheckProbe } from \"./typecheck-probe\";\nimport { parseProbeArguments, probeUsage } from \"./typecheck-probe-args\";\n\nconst main = async () => {\n const args = parseProbeArguments(process.argv.slice(2));\n if (args.mode === \"help\") {\n process.stdout.write(`${probeUsage}\\n`);\n return;\n }\n await runTypecheckProbe({\n repo: process.cwd(),\n project: args.project,\n command: args.command,\n seedDirectory: args.seedDirectory,\n output: (text) => process.stdout.write(text),\n });\n process.stdout.write(\n \"typecheck probe passed: seeded TS2322 detected and clean typecheck passed\\n\",\n );\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `typecheck-probe: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"typecheck-probe-cli.mjs","names":[],"sources":["../src/typecheck-probe.ts","../src/typecheck-probe-args.ts","../src/typecheck-probe-cli.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { open, realpath, stat, unlink } from \"node:fs/promises\";\nimport path, { dirname, isAbsolute, join, relative, resolve } from \"node:path\";\n\nimport { diagnosticSet } from \"./typecheck-parity\";\n\ntype ProbeCommandOptions = {\n command: readonly string[];\n cwd: string;\n signal: AbortSignal;\n};\ntype ProbeCommandResult = { status: number | null; output: string };\n\nconst runProbeCommand = ({ command, cwd, signal }: ProbeCommandOptions) =>\n new Promise<ProbeCommandResult>((done, reject) => {\n const executable = command.at(0);\n if (executable === undefined) {\n reject(new Error(\"typecheck probe command is empty\"));\n return;\n }\n const child = spawn(executable, command.slice(1), {\n cwd,\n signal,\n shell: false,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n let output = \"\";\n child.stdout.on(\"data\", (chunk: Buffer) => {\n output += chunk.toString();\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n output += chunk.toString();\n });\n child.once(\"error\", reject);\n child.once(\"close\", (status) => done({ status, output }));\n });\n\ntype ProbePathContainmentOptions = {\n root: string;\n candidate: string;\n paths?: Pick<typeof path, \"relative\" | \"isAbsolute\" | \"sep\">;\n};\n\nexport const insideProbePath = ({\n root,\n candidate,\n paths = path,\n}: ProbePathContainmentOptions) => {\n const location = paths.relative(root, candidate);\n return (\n location !== \"..\" &&\n !location.startsWith(\"..\" + paths.sep) &&\n !paths.isAbsolute(location)\n );\n};\n\ntype RunTypecheckProbeOptions = {\n repo: string;\n project: string;\n seedDirectory?: string | undefined;\n command: readonly string[];\n output?: (text: string) => void;\n run?: (options: ProbeCommandOptions) => Promise<ProbeCommandResult>;\n};\n\nexport const runTypecheckProbe = async ({\n repo,\n project,\n seedDirectory,\n command,\n output,\n run = runProbeCommand,\n}: RunTypecheckProbeOptions) => {\n const executable = command.at(0);\n if (\n executable === undefined ||\n executable === \"\" ||\n command.some((argument) => argument.includes(\"\\0\"))\n )\n throw new Error(\n \"typecheck probe requires a nonempty command argv without NUL bytes\",\n );\n if (project === \"\")\n throw new Error(\"typecheck probe requires an explicit project file\");\n const root = await realpath(repo);\n const requested = resolve(root, project);\n if (!insideProbePath({ root, candidate: requested }))\n throw new Error(\n `typecheck probe project is outside the repository: ${project}`,\n );\n const config = await realpath(requested);\n if (!insideProbePath({ root, candidate: config }))\n throw new Error(\n `typecheck probe project resolves outside the repository: ${project}`,\n );\n if (!(await stat(config)).isFile())\n throw new Error(`typecheck probe project must be a file: ${project}`);\n let seedParent = dirname(config);\n if (seedDirectory !== undefined) {\n if (seedDirectory === \"\" || isAbsolute(seedDirectory))\n throw new Error(\n \"typecheck probe seed directory must be repository-relative\",\n );\n const requestedSeedParent = resolve(root, seedDirectory);\n if (!insideProbePath({ root, candidate: requestedSeedParent }))\n throw new Error(\n `typecheck probe seed directory is outside the repository: ${seedDirectory}`,\n );\n seedParent = await realpath(requestedSeedParent);\n if (\n !insideProbePath({ root, candidate: seedParent }) ||\n !insideProbePath({ root: dirname(config), candidate: seedParent })\n )\n throw new Error(\n `typecheck probe seed directory must be inside the declared project: ${seedDirectory}`,\n );\n if (!(await stat(seedParent)).isDirectory())\n throw new Error(\n `typecheck probe seed directory must be a directory: ${seedDirectory}`,\n );\n }\n const seed = join(seedParent, `stll-typecheck-probe-${randomUUID()}.ts`);\n const seedLocation = relative(root, seed).replaceAll(\"\\\\\", \"/\");\n const controller = new AbortController();\n const interrupt = (signal: string) =>\n controller.abort(new Error(`typecheck probe interrupted by ${signal}`));\n const onInterrupt = () => interrupt(\"SIGINT\");\n const onTerminate = () => interrupt(\"SIGTERM\");\n process.on(\"SIGINT\", onInterrupt);\n process.on(\"SIGTERM\", onTerminate);\n let created = false;\n const removeSeed = async () => {\n if (!created) return;\n await unlink(seed);\n created = false;\n };\n const execute = async () => {\n controller.signal.throwIfAborted();\n let onAbort: (() => void) | undefined;\n const aborted = new Promise<never>((_done, reject) => {\n onAbort = () => reject(controller.signal.reason);\n controller.signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n try {\n const result = await Promise.race([\n run({ command, cwd: root, signal: controller.signal }),\n aborted,\n ]);\n controller.signal.throwIfAborted();\n output?.(result.output);\n return result;\n } finally {\n if (onAbort !== undefined)\n controller.signal.removeEventListener(\"abort\", onAbort);\n }\n };\n try {\n controller.signal.throwIfAborted();\n const file = await open(seed, \"wx\", 0o600);\n created = true;\n try {\n await file.writeFile('export const typecheckProbe: number = \"wrong\";\\n');\n } finally {\n await file.close();\n }\n const seeded = await execute();\n if (seeded.status === null || seeded.status === 0)\n throw new Error(\n `typecheck probe expected the seeded command to fail: ${seedLocation}`,\n );\n // Workspace runners may report compiler paths from the declared project.\n // Only the exact owned seed under either known command origin is accepted.\n const origins = new Set([root, dirname(config)]);\n const attributed = [...origins].some((origin) =>\n diagnosticSet(seeded.output, origin).includes(\n `${relative(origin, seed).replaceAll(\"\\\\\", \"/\")}:1:2322`,\n ),\n );\n if (!attributed)\n throw new Error(\n `typecheck probe expected TS2322 attributed to ${seedLocation}; the declared project may exclude the seed`,\n );\n await removeSeed();\n const clean = await execute();\n if (clean.status !== 0)\n throw new Error(\n `typecheck probe clean command failed with status ${clean.status ?? \"unknown\"}: ${project}`,\n );\n } finally {\n try {\n await removeSeed();\n } finally {\n process.removeListener(\"SIGINT\", onInterrupt);\n process.removeListener(\"SIGTERM\", onTerminate);\n }\n }\n};\n","export const probeUsage =\n \"Usage: stll-typecheck-probe --project <tsconfig> [--seed-dir <directory>] -- <command> [args...]\\n stll-typecheck-probe --help\";\n\nexport const parseProbeArguments = (args: readonly string[]) => {\n if (args.length === 1 && args.at(0) === \"--help\")\n return { mode: \"help\" } as const;\n const project = args.at(1);\n const seedDirectory = args.at(2) === \"--seed-dir\" ? args.at(3) : undefined;\n const separator = seedDirectory === undefined ? 2 : 4;\n const command = args.slice(separator + 1);\n if (\n args.at(0) !== \"--project\" ||\n project === undefined ||\n project.trim() === \"\" ||\n project.startsWith(\"-\") ||\n args.at(separator) !== \"--\" ||\n (seedDirectory !== undefined &&\n (seedDirectory.trim() === \"\" || seedDirectory.startsWith(\"-\"))) ||\n command.length === 0 ||\n command.some((value) => value.trim() === \"\")\n )\n throw new Error(probeUsage);\n return {\n mode: \"probe\",\n project,\n command,\n ...(seedDirectory === undefined ? {} : { seedDirectory }),\n } as const;\n};\n","#!/usr/bin/env node\nimport { runTypecheckProbe } from \"./typecheck-probe\";\nimport { parseProbeArguments, probeUsage } from \"./typecheck-probe-args\";\n\nconst main = async () => {\n const args = parseProbeArguments(process.argv.slice(2));\n if (args.mode === \"help\") {\n process.stdout.write(`${probeUsage}\\n`);\n return;\n }\n await runTypecheckProbe({\n repo: process.cwd(),\n project: args.project,\n command: args.command,\n seedDirectory: args.seedDirectory,\n output: (text) => process.stdout.write(text),\n });\n process.stdout.write(\n \"typecheck probe passed: seeded TS2322 detected and clean typecheck passed\\n\",\n );\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `typecheck-probe: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/oxlint-config",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Shared general oxlint configuration for stella packages.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"bin": {
|
|
12
12
|
"stll-cloud-setup": "./dist/cloud-setup-cli.mjs",
|
|
13
13
|
"stll-consumer-compat": "./dist/consumer-compat-cli.mjs",
|
|
14
|
+
"stll-dependabot": "./dist/dependabot-cli.mjs",
|
|
14
15
|
"stll-publish-contract": "./dist/publish-contract-cli.mjs",
|
|
15
16
|
"stll-toolchain-changed": "./dist/toolchain-changed-cli.mjs",
|
|
16
17
|
"stll-toolchain-check": "./dist/toolchain-check-cli.mjs",
|
|
@@ -81,6 +82,17 @@
|
|
|
81
82
|
"default": "./dist/publish-build-target-vite-dts-helper.cjs"
|
|
82
83
|
},
|
|
83
84
|
"default": "./dist/publish-build-target-vite-dts-helper.mjs"
|
|
85
|
+
},
|
|
86
|
+
"./dependabot": {
|
|
87
|
+
"import": {
|
|
88
|
+
"types": "./dist/dependabot.d.mts",
|
|
89
|
+
"default": "./dist/dependabot.mjs"
|
|
90
|
+
},
|
|
91
|
+
"require": {
|
|
92
|
+
"types": "./dist/dependabot.d.cts",
|
|
93
|
+
"default": "./dist/dependabot.cjs"
|
|
94
|
+
},
|
|
95
|
+
"default": "./dist/dependabot.mjs"
|
|
84
96
|
}
|
|
85
97
|
},
|
|
86
98
|
"publishConfig": {
|