workspace-conformance 1.3.0 → 1.5.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 +24 -1
- package/dist/cli.js +286 -13
- package/dist/index.cjs +288 -12
- package/dist/index.d.cts +82 -1
- package/dist/index.d.ts +82 -1
- package/dist/index.js +287 -14
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -100,6 +100,23 @@ function expandTemplate(template, values) {
|
|
|
100
100
|
return value;
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
|
+
const NAME_PLACEHOLDER = "{name}";
|
|
104
|
+
/**
|
|
105
|
+
* What a name template must be, as a configuration error says it. It does not quote the template, as no configuration error quotes a value.
|
|
106
|
+
*/
|
|
107
|
+
const NAME_TEMPLATE_REQUIREMENT = "needs {name} exactly once, other text beside it and no other placeholder";
|
|
108
|
+
const ANY_PLACEHOLDER = /\{[a-z]+\}/u;
|
|
109
|
+
/**
|
|
110
|
+
* `template` split at `{name}`, or `undefined` unless it holds `{name}` exactly once, other text beside it and no other placeholder. Without other text every name would match, and with `{name}` twice a name could be split more than one way.
|
|
111
|
+
*/
|
|
112
|
+
function parseNameTemplate(template) {
|
|
113
|
+
const [before, after, ...rest] = template.split(NAME_PLACEHOLDER);
|
|
114
|
+
if (before === void 0 || after === void 0 || rest.length > 0 || before + after === "" || ANY_PLACEHOLDER.test(before + after)) return;
|
|
115
|
+
return {
|
|
116
|
+
before,
|
|
117
|
+
after
|
|
118
|
+
};
|
|
119
|
+
}
|
|
103
120
|
//#endregion
|
|
104
121
|
//#region src/ts-project.ts
|
|
105
122
|
/**
|
|
@@ -213,6 +230,123 @@ const aggregateMappers = async ({ cwd, options }) => {
|
|
|
213
230
|
return violations.sort((a, b) => a.file.localeCompare(b.file) || (a.location?.line ?? 0) - (b.location?.line ?? 0) || a.message.localeCompare(b.message));
|
|
214
231
|
};
|
|
215
232
|
//#endregion
|
|
233
|
+
//#region src/checks/codec-pairs.ts
|
|
234
|
+
function collect(container, prefix, found, entered) {
|
|
235
|
+
for (const [name, declarations] of container.getExportedDeclarations()) {
|
|
236
|
+
const value = declarations.find((declaration) => !ts_morph.Node.isInterfaceDeclaration(declaration) && !ts_morph.Node.isTypeAliasDeclaration(declaration) && !ts_morph.Node.isModuleDeclaration(declaration) && !ts_morph.Node.isSourceFile(declaration));
|
|
237
|
+
if (value !== void 0) found.set(`${prefix}${name}`, value);
|
|
238
|
+
for (const member of declarations) if (ts_morph.Node.isModuleDeclaration(member)) collect(member, `${prefix}${name}.`, found, entered);
|
|
239
|
+
else if (ts_morph.Node.isSourceFile(member) && !entered.has(member)) collect(member, `${prefix}${name}.`, found, /* @__PURE__ */ new Set([...entered, member]));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* The values `file` exports, by name, wherever they are declared: a re-export counts. Those inside an exported namespace, or in a module re-exported as a namespace (`export * as ns from './x'`), are included under their qualified name (`Namespace.value`). Interfaces and type aliases are types, not codecs, and a namespace is where codecs live rather than one itself, so all three are left out.
|
|
244
|
+
*/
|
|
245
|
+
function exportedValues(file) {
|
|
246
|
+
const found = /* @__PURE__ */ new Map();
|
|
247
|
+
collect(file, "", found, /* @__PURE__ */ new Set([file]));
|
|
248
|
+
return found;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Where the declaration's name is written, or where the declaration starts when it has no name node.
|
|
252
|
+
*/
|
|
253
|
+
function valueLocation(declaration) {
|
|
254
|
+
const nameNode = ts_morph.Node.hasName(declaration) ? declaration.getNameNode() : void 0;
|
|
255
|
+
const { line, column } = declaration.getSourceFile().getLineAndColumnAtPos((nameNode ?? declaration).getStart());
|
|
256
|
+
return {
|
|
257
|
+
line,
|
|
258
|
+
column
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* The template of an option, which the configuration has already validated; a template that does not parse is a configuration error naming the option.
|
|
263
|
+
*/
|
|
264
|
+
function templateOf(options, option) {
|
|
265
|
+
const template = parseNameTemplate(options[option]);
|
|
266
|
+
if (template === void 0) throw new ConformanceError(`checks.codec-pairs.${option}: ${NAME_TEMPLATE_REQUIREMENT}`);
|
|
267
|
+
return template;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* The shared name a qualified export name gives under `template`, or `undefined` when its last segment does not fit the template. The namespace part is kept apart so a counterpart is looked for in the same namespace.
|
|
271
|
+
*/
|
|
272
|
+
function sharedName(qualified, template) {
|
|
273
|
+
const namespace = qualified.slice(0, qualified.lastIndexOf(".") + 1);
|
|
274
|
+
const local = qualified.slice(namespace.length);
|
|
275
|
+
if (local.length <= template.before.length + template.after.length || !local.startsWith(template.before) || !local.endsWith(template.after)) return;
|
|
276
|
+
return {
|
|
277
|
+
namespace,
|
|
278
|
+
name: local.slice(template.before.length, local.length - template.after.length)
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Every encoder a codec file exports has the decoder its name implies, exported by the same file, and every decoder the encoder. A name is an encoder or a decoder when it fits that template; other exports are not codecs and are not judged. A half re-exported from another file counts, and is reported where it is declared.
|
|
283
|
+
*
|
|
284
|
+
* It checks that the counterpart is exported, not that the two round-trip: that is a property test of the repository's own.
|
|
285
|
+
*/
|
|
286
|
+
const codecPairs = async ({ cwd, options }) => {
|
|
287
|
+
const { project, files } = await createProject(cwd, options.tsConfig, options.codecs, {
|
|
288
|
+
check: "codec-pairs",
|
|
289
|
+
files: "codecs"
|
|
290
|
+
});
|
|
291
|
+
const excluded = new Set(options.exclude);
|
|
292
|
+
const encoder = templateOf(options, "encoder");
|
|
293
|
+
const decoder = templateOf(options, "decoder");
|
|
294
|
+
const halves = [{
|
|
295
|
+
template: encoder,
|
|
296
|
+
counterpart: decoder,
|
|
297
|
+
missing: "decoder"
|
|
298
|
+
}, {
|
|
299
|
+
template: decoder,
|
|
300
|
+
counterpart: encoder,
|
|
301
|
+
missing: "encoder"
|
|
302
|
+
}];
|
|
303
|
+
const violations = [];
|
|
304
|
+
for (const file of files) {
|
|
305
|
+
const values = exportedValues(project.getSourceFileOrThrow((0, node_path.resolve)(cwd, file)));
|
|
306
|
+
for (const [qualified, declaration] of values) {
|
|
307
|
+
if (excluded.has(qualified)) continue;
|
|
308
|
+
for (const { template, counterpart, missing } of halves) {
|
|
309
|
+
const shared = sharedName(qualified, template);
|
|
310
|
+
if (shared === void 0) continue;
|
|
311
|
+
const expected = `${shared.namespace}${counterpart.before}${shared.name}${counterpart.after}`;
|
|
312
|
+
if (!values.has(expected)) violations.push({
|
|
313
|
+
code: `codec-pairs/missing-${missing}`,
|
|
314
|
+
message: `${qualified} has no ${missing}: ${file} does not export ${expected}`,
|
|
315
|
+
file: relativePosix(cwd, declaration.getSourceFile().getFilePath()),
|
|
316
|
+
location: valueLocation(declaration)
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return violations.sort((a, b) => a.file.localeCompare(b.file) || (a.location?.line ?? 0) - (b.location?.line ?? 0) || a.message.localeCompare(b.message));
|
|
322
|
+
};
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/checks/type-references.ts
|
|
325
|
+
/**
|
|
326
|
+
* The identifier a reference ends in: `infer` in `z.infer`, the name itself when it is not qualified.
|
|
327
|
+
*/
|
|
328
|
+
function lastIdentifier(reference) {
|
|
329
|
+
if (ts_morph.Node.isQualifiedName(reference)) return reference.getRight();
|
|
330
|
+
if (ts_morph.Node.isPropertyAccessExpression(reference)) return reference.getNameNode();
|
|
331
|
+
return reference;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* The declarations the identifier refers to, through any imports and re-exports.
|
|
335
|
+
*/
|
|
336
|
+
function declarationsOf(identifier) {
|
|
337
|
+
const symbol = identifier.getSymbol();
|
|
338
|
+
return (symbol?.getAliasedSymbol() ?? symbol)?.getDeclarations() ?? [];
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* The names a reference goes by: the last name as written, and the name it was declared with when that differs, as for `Infer` in `import type { infer as Infer } from 'zod'`, which is also `infer`. A library may itself re-export a generic under another name, so both count.
|
|
342
|
+
*/
|
|
343
|
+
function referenceNames(reference) {
|
|
344
|
+
const identifier = lastIdentifier(reference);
|
|
345
|
+
const symbol = identifier.getSymbol();
|
|
346
|
+
const declared = (symbol?.getAliasedSymbol() ?? symbol)?.getName();
|
|
347
|
+
return declared === void 0 ? [identifier.getText()] : [.../* @__PURE__ */ new Set([identifier.getText(), declared])];
|
|
348
|
+
}
|
|
349
|
+
//#endregion
|
|
216
350
|
//#region src/checks/command-types.ts
|
|
217
351
|
/**
|
|
218
352
|
* The last names of the generics that turn a schema into its type, used when the options name none: `z.infer`, `z.input`, `z.output`, `z.TypeOf` and Valibot's `InferInput` and `InferOutput`.
|
|
@@ -230,20 +364,10 @@ const DEFAULT_INFERENCES = [
|
|
|
230
364
|
*/
|
|
231
365
|
const STANDARD_SCHEMA_MEMBER = "~standard";
|
|
232
366
|
/**
|
|
233
|
-
* The names a type reference goes by: the last name as written, and the name it was declared with when that differs, as for `Infer` in `import type { infer as Infer } from 'zod'`, which is also `infer`. A library may itself re-export a generic under another name, so both count.
|
|
234
|
-
*/
|
|
235
|
-
function namesOf(typeName) {
|
|
236
|
-
const identifier = ts_morph.Node.isQualifiedName(typeName) ? typeName.getRight() : typeName;
|
|
237
|
-
const symbol = identifier.getSymbol();
|
|
238
|
-
const declared = (symbol?.getAliasedSymbol() ?? symbol)?.getName();
|
|
239
|
-
return declared === void 0 ? [identifier.getText()] : [.../* @__PURE__ */ new Set([identifier.getText(), declared])];
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
367
|
* The local alias without type parameters that a type reference names, or `undefined` when it names anything else. Such an alias is a name for the type it is written as, so it is judged by that.
|
|
243
368
|
*/
|
|
244
369
|
function aliasNamed(typeName) {
|
|
245
|
-
const
|
|
246
|
-
const declaration = (symbol?.getAliasedSymbol() ?? symbol)?.getDeclarations().find(ts_morph.Node.isTypeAliasDeclaration);
|
|
370
|
+
const declaration = declarationsOf(lastIdentifier(typeName)).find(ts_morph.Node.isTypeAliasDeclaration);
|
|
247
371
|
return declaration?.getTypeParameters().length === 0 ? declaration : void 0;
|
|
248
372
|
}
|
|
249
373
|
/**
|
|
@@ -256,7 +380,7 @@ function problem$1(declaration, name, inferences, followed = /* @__PURE__ */ new
|
|
|
256
380
|
};
|
|
257
381
|
const written = declaration.getTypeNode();
|
|
258
382
|
if (ts_morph.Node.isTypeReference(written)) {
|
|
259
|
-
const inference =
|
|
383
|
+
const inference = referenceNames(written.getTypeName()).find((candidate) => inferences.includes(candidate));
|
|
260
384
|
if (inference !== void 0) {
|
|
261
385
|
const [argument] = written.getTypeArguments();
|
|
262
386
|
if (argument !== void 0 && ts_morph.Node.isTypeQuery(argument) && argument.getExprName().getType().getProperty(STANDARD_SCHEMA_MEMBER) !== void 0) return;
|
|
@@ -452,6 +576,120 @@ const commitTypes = async ({ cwd, options, configFiles }) => {
|
|
|
452
576
|
return violations;
|
|
453
577
|
};
|
|
454
578
|
//#endregion
|
|
579
|
+
//#region src/checks/derived-types.ts
|
|
580
|
+
/**
|
|
581
|
+
* The last names that count as inference when the options name none: those of `command-types`, Drizzle's `InferSelectModel` and `InferInsertModel` generics, and the `$inferSelect` and `$inferInsert` members of a Drizzle table, read as `typeof table.$inferSelect`.
|
|
582
|
+
*/
|
|
583
|
+
const DEFAULT_DERIVED_TYPE_INFERENCES = [
|
|
584
|
+
...DEFAULT_INFERENCES,
|
|
585
|
+
"InferSelectModel",
|
|
586
|
+
"InferInsertModel",
|
|
587
|
+
"$inferSelect",
|
|
588
|
+
"$inferInsert"
|
|
589
|
+
];
|
|
590
|
+
/**
|
|
591
|
+
* Whether the node names something declared in one of the schema files.
|
|
592
|
+
*/
|
|
593
|
+
function declaredInSchema(name, derivation) {
|
|
594
|
+
const identifier = ts_morph.Node.isIdentifier(name) ? name : ts_morph.Node.isQualifiedName(name) ? name.getRight() : void 0;
|
|
595
|
+
return identifier !== void 0 && declarationsOf(identifier).some((declaration) => derivation.schemaFiles.has(relativePosix(derivation.cwd, declaration.getSourceFile().getFilePath())));
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* The interface or type alias without type parameters a reference names, when it has not been followed yet. Such a declaration is a name for what it is written as, so it is judged by that.
|
|
599
|
+
*/
|
|
600
|
+
function followable(reference, derivation) {
|
|
601
|
+
const name = ts_morph.Node.isTypeReference(reference) ? reference.getTypeName() : reference.getExpression();
|
|
602
|
+
if (!ts_morph.Node.isIdentifier(name) && !ts_morph.Node.isQualifiedName(name) && !ts_morph.Node.isPropertyAccessExpression(name)) return;
|
|
603
|
+
const declaration = declarationsOf(lastIdentifier(name)).find((found) => ts_morph.Node.isTypeAliasDeclaration(found) || ts_morph.Node.isInterfaceDeclaration(found));
|
|
604
|
+
return declaration?.getTypeParameters().length === 0 && !derivation.followed.has(declaration) ? declaration : void 0;
|
|
605
|
+
}
|
|
606
|
+
function isNullish(node) {
|
|
607
|
+
return node.getKind() === ts_morph.SyntaxKind.UndefinedKeyword || ts_morph.Node.isLiteralTypeNode(node) && node.getLiteral().getKind() === ts_morph.SyntaxKind.NullKeyword;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Whether a reference is derived: an inference applied to `typeof schema`, an alias or interface that is itself derived, or another generic given a derived type, as `Partial<Order>` is.
|
|
611
|
+
*/
|
|
612
|
+
function derivedReference(reference, derivation) {
|
|
613
|
+
const name = ts_morph.Node.isTypeReference(reference) ? reference.getTypeName() : reference.getExpression();
|
|
614
|
+
if ((ts_morph.Node.isIdentifier(name) || ts_morph.Node.isQualifiedName(name) || ts_morph.Node.isPropertyAccessExpression(name)) && referenceNames(name).some((candidate) => derivation.inferences.has(candidate))) {
|
|
615
|
+
const [argument] = reference.getTypeArguments();
|
|
616
|
+
return argument !== void 0 && ts_morph.Node.isTypeQuery(argument) && declaredInSchema(argument.getExprName(), derivation);
|
|
617
|
+
}
|
|
618
|
+
const declaration = followable(reference, derivation);
|
|
619
|
+
if (declaration !== void 0) return derivedDeclaration(declaration, {
|
|
620
|
+
...derivation,
|
|
621
|
+
followed: /* @__PURE__ */ new Set([...derivation.followed, declaration])
|
|
622
|
+
});
|
|
623
|
+
return reference.getTypeArguments().some((argument) => derivedType(argument, derivation));
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Whether a type, as written, is derived from a schema. A type literal is written by hand whatever its members are.
|
|
627
|
+
*/
|
|
628
|
+
function derivedType(node, derivation) {
|
|
629
|
+
if (ts_morph.Node.isTypeReference(node) || ts_morph.Node.isExpressionWithTypeArguments(node)) return derivedReference(node, derivation);
|
|
630
|
+
if (ts_morph.Node.isTypeQuery(node)) {
|
|
631
|
+
const name = node.getExprName();
|
|
632
|
+
return ts_morph.Node.isQualifiedName(name) && referenceNames(name).some((candidate) => derivation.inferences.has(candidate)) && declaredInSchema(name.getLeft(), derivation);
|
|
633
|
+
}
|
|
634
|
+
if (ts_morph.Node.isParenthesizedTypeNode(node) || ts_morph.Node.isTypeOperatorTypeNode(node)) return derivedType(node.getTypeNode(), derivation);
|
|
635
|
+
if (ts_morph.Node.isArrayTypeNode(node)) return derivedType(node.getElementTypeNode(), derivation);
|
|
636
|
+
if (ts_morph.Node.isIndexedAccessTypeNode(node)) return derivedType(node.getObjectTypeNode(), derivation);
|
|
637
|
+
if (ts_morph.Node.isIntersectionTypeNode(node)) return node.getTypeNodes().some((member) => derivedType(member, derivation));
|
|
638
|
+
if (ts_morph.Node.isUnionTypeNode(node)) {
|
|
639
|
+
const members = node.getTypeNodes().filter((member) => !isNullish(member));
|
|
640
|
+
return members.length > 0 && members.every((member) => derivedType(member, derivation));
|
|
641
|
+
}
|
|
642
|
+
return false;
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Whether an interface or type alias is derived: an alias by the type it is written as, an interface by whether it extends a derived type.
|
|
646
|
+
*/
|
|
647
|
+
function derivedDeclaration(declaration, derivation) {
|
|
648
|
+
if (ts_morph.Node.isInterfaceDeclaration(declaration)) return declaration.getExtends().some((heritage) => derivedReference(heritage, derivation));
|
|
649
|
+
return derivedType(declaration.getTypeNodeOrThrow(), derivation);
|
|
650
|
+
}
|
|
651
|
+
async function pairViolations(cwd, options, pair, index) {
|
|
652
|
+
const { project, files } = await createProject(cwd, options.tsConfig, pair.types, {
|
|
653
|
+
check: "derived-types",
|
|
654
|
+
files: `pairs.${String(index)}.types`
|
|
655
|
+
});
|
|
656
|
+
const schemaFiles = await findFiles(cwd, pair.schemas);
|
|
657
|
+
if (schemaFiles.length === 0) throw new ConformanceError(`checks.derived-types.pairs.${String(index)}.schemas: no file matches`);
|
|
658
|
+
const excluded = new Set(options.exclude);
|
|
659
|
+
const derivation = {
|
|
660
|
+
inferences: new Set(options.inferences ?? DEFAULT_DERIVED_TYPE_INFERENCES),
|
|
661
|
+
schemaFiles: new Set(schemaFiles),
|
|
662
|
+
cwd,
|
|
663
|
+
followed: /* @__PURE__ */ new Set()
|
|
664
|
+
};
|
|
665
|
+
const seen = /* @__PURE__ */ new Set();
|
|
666
|
+
const violations = [];
|
|
667
|
+
for (const file of files) for (const [name, declaration] of exportedTypes(project.getSourceFileOrThrow((0, node_path.resolve)(cwd, file)))) {
|
|
668
|
+
if (excluded.has(name) || seen.has(declaration)) continue;
|
|
669
|
+
seen.add(declaration);
|
|
670
|
+
if (!derivedDeclaration(declaration, {
|
|
671
|
+
...derivation,
|
|
672
|
+
followed: /* @__PURE__ */ new Set([declaration])
|
|
673
|
+
})) violations.push({
|
|
674
|
+
code: "derived-types/not-derived",
|
|
675
|
+
message: `${name} is not derived from a schema in ${pair.schemas.join(", ")}: nothing in its definition applies an inference generic to one`,
|
|
676
|
+
file: relativePosix(cwd, declaration.getSourceFile().getFilePath()),
|
|
677
|
+
location: declarationLocation(declaration)
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
return violations;
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* For each pair, every exported interface and type alias of its type files is derived from a schema declared in its schema files: somewhere in its definition an inference (a generic in `inferences`, such as `z.infer` or `InferSelectModel`) is applied to `typeof schema`, or an inference member is read from it (`typeof table.$inferSelect`).
|
|
684
|
+
*
|
|
685
|
+
* The definition is followed through aliases and interfaces without type parameters, in any file, and through the arguments of other generics, intersections, unions whose members are all derived (`null` and `undefined` aside), arrays, type operators and indexed access. A type literal, and a schema passed to a generic that is not an inference, are written by hand.
|
|
686
|
+
*/
|
|
687
|
+
const derivedTypes = async ({ cwd, options }) => {
|
|
688
|
+
const violations = [];
|
|
689
|
+
for (const [index, pair] of options.pairs.entries()) violations.push(...await pairViolations(cwd, options, pair, index));
|
|
690
|
+
return violations.sort((a, b) => a.file.localeCompare(b.file) || (a.location?.line ?? 0) - (b.location?.line ?? 0) || a.message.localeCompare(b.message));
|
|
691
|
+
};
|
|
692
|
+
//#endregion
|
|
455
693
|
//#region src/checks/dockerfile-package-manager.ts
|
|
456
694
|
const DEFAULT_DOCKERFILES = [
|
|
457
695
|
"**/Dockerfile",
|
|
@@ -2941,6 +3179,10 @@ function compiles(source) {
|
|
|
2941
3179
|
*/
|
|
2942
3180
|
const pattern = zod.z.string().min(1).refine(compiles, "not a valid regular expression");
|
|
2943
3181
|
const patterns = zod.z.array(pattern);
|
|
3182
|
+
/**
|
|
3183
|
+
* A name template of `codec-pairs`.
|
|
3184
|
+
*/
|
|
3185
|
+
const nameTemplate = zod.z.string().refine((template) => parseNameTemplate(template) !== void 0, NAME_TEMPLATE_REQUIREMENT);
|
|
2944
3186
|
const severity = zod.z.enum(["warn", "error"]);
|
|
2945
3187
|
const requiredRules = zod.z.record(zod.z.string().min(1), severity);
|
|
2946
3188
|
const selection = {
|
|
@@ -2973,12 +3215,31 @@ const checks = zod.z.strictObject({
|
|
|
2973
3215
|
exclude: zod.z.exactOptional(names),
|
|
2974
3216
|
tsConfig: zod.z.exactOptional(path)
|
|
2975
3217
|
}))),
|
|
3218
|
+
"codec-pairs": zod.z.exactOptional(enabled(zod.z.strictObject({
|
|
3219
|
+
codecs: paths,
|
|
3220
|
+
encoder: nameTemplate,
|
|
3221
|
+
decoder: nameTemplate,
|
|
3222
|
+
exclude: zod.z.exactOptional(names),
|
|
3223
|
+
tsConfig: zod.z.exactOptional(path)
|
|
3224
|
+
}).refine((options) => options.encoder !== options.decoder, {
|
|
3225
|
+
path: ["decoder"],
|
|
3226
|
+
message: "the decoder template is the encoder template, so every name would be its own pair"
|
|
3227
|
+
}))),
|
|
2976
3228
|
"command-types": zod.z.exactOptional(enabled(zod.z.strictObject({
|
|
2977
3229
|
commands: paths,
|
|
2978
3230
|
exclude: zod.z.exactOptional(names),
|
|
2979
3231
|
inferences: zod.z.exactOptional(paths),
|
|
2980
3232
|
tsConfig: zod.z.exactOptional(path)
|
|
2981
3233
|
}))),
|
|
3234
|
+
"derived-types": zod.z.exactOptional(enabled(zod.z.strictObject({
|
|
3235
|
+
pairs: zod.z.array(zod.z.strictObject({
|
|
3236
|
+
schemas: paths,
|
|
3237
|
+
types: paths
|
|
3238
|
+
})).min(1),
|
|
3239
|
+
exclude: zod.z.exactOptional(names),
|
|
3240
|
+
inferences: zod.z.exactOptional(paths),
|
|
3241
|
+
tsConfig: zod.z.exactOptional(path)
|
|
3242
|
+
}))),
|
|
2982
3243
|
"import-uphill": zod.z.exactOptional(enabled(importGraph)),
|
|
2983
3244
|
"import-rank-skip": zod.z.exactOptional(enabled(importGraph)),
|
|
2984
3245
|
"import-cross-slice": zod.z.exactOptional(enabled(importGraph)),
|
|
@@ -3220,12 +3481,24 @@ const registry = {
|
|
|
3220
3481
|
select: (checks) => enabledOptions(checks["aggregate-mappers"]),
|
|
3221
3482
|
check: aggregateMappers
|
|
3222
3483
|
}),
|
|
3484
|
+
"codec-pairs": plain({
|
|
3485
|
+
name: "codec-pairs",
|
|
3486
|
+
description: "Every exported encoder in a codec file has a decoder under the naming templates, and every decoder an encoder",
|
|
3487
|
+
select: (checks) => enabledOptions(checks["codec-pairs"]),
|
|
3488
|
+
check: codecPairs
|
|
3489
|
+
}),
|
|
3223
3490
|
"command-types": plain({
|
|
3224
3491
|
name: "command-types",
|
|
3225
3492
|
description: "Every exported command type is derived from a schema, not hand-written",
|
|
3226
3493
|
select: (checks) => enabledOptions(checks["command-types"]),
|
|
3227
3494
|
check: commandTypes
|
|
3228
3495
|
}),
|
|
3496
|
+
"derived-types": plain({
|
|
3497
|
+
name: "derived-types",
|
|
3498
|
+
description: "Every exported type in a file paired with schema files is derived from one of those schemas, not hand-written",
|
|
3499
|
+
select: (checks) => enabledOptions(checks["derived-types"]),
|
|
3500
|
+
check: derivedTypes
|
|
3501
|
+
}),
|
|
3229
3502
|
"import-uphill": importCheck({
|
|
3230
3503
|
name: "import-uphill",
|
|
3231
3504
|
description: "No package imports a package of a higher rank",
|
|
@@ -3574,6 +3847,7 @@ function proveExhaustive(input) {
|
|
|
3574
3847
|
}
|
|
3575
3848
|
//#endregion
|
|
3576
3849
|
exports.ConformanceError = ConformanceError;
|
|
3850
|
+
exports.DEFAULT_DERIVED_TYPE_INFERENCES = DEFAULT_DERIVED_TYPE_INFERENCES;
|
|
3577
3851
|
exports.DEFAULT_INFERENCES = DEFAULT_INFERENCES;
|
|
3578
3852
|
exports.DEFAULT_WORKFLOWS = DEFAULT_WORKFLOWS;
|
|
3579
3853
|
exports.EXIT_CODES = EXIT_CODES;
|
|
@@ -3583,6 +3857,7 @@ exports.accessOf = accessOf;
|
|
|
3583
3857
|
exports.aggregateMappers = aggregateMappers;
|
|
3584
3858
|
exports.checkNames = checkNames;
|
|
3585
3859
|
exports.classifyPackages = classifyPackages;
|
|
3860
|
+
exports.codecPairs = codecPairs;
|
|
3586
3861
|
exports.commandTypes = commandTypes;
|
|
3587
3862
|
exports.commitTypes = commitTypes;
|
|
3588
3863
|
exports.conformanceSchema = conformanceSchema;
|
|
@@ -3591,6 +3866,7 @@ exports.createGitHubClient = createGitHubClient;
|
|
|
3591
3866
|
exports.crossSliceRules = crossSliceRules;
|
|
3592
3867
|
exports.cycleRule = cycleRule;
|
|
3593
3868
|
exports.deployTools = deployTools;
|
|
3869
|
+
exports.derivedTypes = derivedTypes;
|
|
3594
3870
|
exports.dockerfilePackageManager = dockerfilePackageManager;
|
|
3595
3871
|
exports.effectiveEnv = effectiveEnv;
|
|
3596
3872
|
exports.effectivePermissions = effectivePermissions;
|
package/dist/index.d.cts
CHANGED
|
@@ -376,6 +376,31 @@ interface AggregateMappersOptions {
|
|
|
376
376
|
*/
|
|
377
377
|
readonly tsConfig?: string;
|
|
378
378
|
}
|
|
379
|
+
/**
|
|
380
|
+
* Options of the `codec-pairs` check: every encoder a codec file exports has a decoder it also exports, and every decoder an encoder.
|
|
381
|
+
*/
|
|
382
|
+
interface CodecPairsOptions {
|
|
383
|
+
/**
|
|
384
|
+
* Globs of the codec files, relative to the directory the checks run in. Each file is judged on its own exports, re-exports included.
|
|
385
|
+
*/
|
|
386
|
+
readonly codecs: readonly string[];
|
|
387
|
+
/**
|
|
388
|
+
* The name of an encoder, with `{name}` standing for the name it shares with its decoder, such as `encode{name}` or `{name}Encoder`. `{name}` appears exactly once, beside other text, and is the only placeholder.
|
|
389
|
+
*/
|
|
390
|
+
readonly encoder: string;
|
|
391
|
+
/**
|
|
392
|
+
* The name of a decoder, in the same form as `encoder` and different from it.
|
|
393
|
+
*/
|
|
394
|
+
readonly decoder: string;
|
|
395
|
+
/**
|
|
396
|
+
* Names of exported encoders and decoders that need no counterpart, such as an encoder for a format that is only ever written.
|
|
397
|
+
*/
|
|
398
|
+
readonly exclude?: readonly string[];
|
|
399
|
+
/**
|
|
400
|
+
* The tsconfig that supplies compiler options and module resolution; `tsconfig.json` when omitted.
|
|
401
|
+
*/
|
|
402
|
+
readonly tsConfig?: string;
|
|
403
|
+
}
|
|
379
404
|
/**
|
|
380
405
|
* Options of the `command-types` check: every command type a file exports is derived from a schema.
|
|
381
406
|
*/
|
|
@@ -397,6 +422,40 @@ interface CommandTypesOptions {
|
|
|
397
422
|
*/
|
|
398
423
|
readonly tsConfig?: string;
|
|
399
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* A set of schema files and the files whose exported types must be derived from those schemas.
|
|
427
|
+
*/
|
|
428
|
+
interface DerivedTypesPair {
|
|
429
|
+
/**
|
|
430
|
+
* Globs of the files that declare the schemas, relative to the directory the checks run in.
|
|
431
|
+
*/
|
|
432
|
+
readonly schemas: readonly string[];
|
|
433
|
+
/**
|
|
434
|
+
* Globs of the files whose exported interfaces and type aliases must be derived from a schema declared in `schemas`.
|
|
435
|
+
*/
|
|
436
|
+
readonly types: readonly string[];
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Options of the `derived-types` check: every type a file exports is derived from a schema of its pair.
|
|
440
|
+
*/
|
|
441
|
+
interface DerivedTypesOptions {
|
|
442
|
+
/**
|
|
443
|
+
* The schema files and the type files that must derive from them. Each type file is judged against the schemas of every pair that lists it.
|
|
444
|
+
*/
|
|
445
|
+
readonly pairs: readonly DerivedTypesPair[];
|
|
446
|
+
/**
|
|
447
|
+
* Names of exported types that are deliberately written by hand.
|
|
448
|
+
*/
|
|
449
|
+
readonly exclude?: readonly string[];
|
|
450
|
+
/**
|
|
451
|
+
* The last names of the generics that turn a schema into its type, and of the members that hold it, such as `infer` in `z.infer<typeof schema>` and `$inferSelect` in `typeof table.$inferSelect`. `infer`, `input`, `output`, `TypeOf`, `InferInput`, `InferOutput`, `InferSelectModel`, `InferInsertModel`, `$inferSelect` and `$inferInsert` when omitted.
|
|
452
|
+
*/
|
|
453
|
+
readonly inferences?: readonly string[];
|
|
454
|
+
/**
|
|
455
|
+
* The tsconfig that supplies compiler options and module resolution; `tsconfig.json` when omitted.
|
|
456
|
+
*/
|
|
457
|
+
readonly tsConfig?: string;
|
|
458
|
+
}
|
|
400
459
|
/**
|
|
401
460
|
* Options shared by the checks that cruise the workspace's import graph.
|
|
402
461
|
*/
|
|
@@ -703,7 +762,9 @@ type SettingsReviewThreadResolutionOptions = SettingsOptions;
|
|
|
703
762
|
*/
|
|
704
763
|
interface CheckOptionsByName {
|
|
705
764
|
readonly "aggregate-mappers": AggregateMappersOptions;
|
|
765
|
+
readonly "codec-pairs": CodecPairsOptions;
|
|
706
766
|
readonly "command-types": CommandTypesOptions;
|
|
767
|
+
readonly "derived-types": DerivedTypesOptions;
|
|
707
768
|
readonly "import-uphill": ImportGraphOptions;
|
|
708
769
|
readonly "import-rank-skip": ImportGraphOptions;
|
|
709
770
|
readonly "import-cross-slice": ImportGraphOptions;
|
|
@@ -741,6 +802,14 @@ type CheckName = keyof CheckOptionsByName;
|
|
|
741
802
|
*/
|
|
742
803
|
export declare const aggregateMappers: CheckFunction<AggregateMappersOptions>;
|
|
743
804
|
//#endregion
|
|
805
|
+
//#region src/checks/codec-pairs.d.ts
|
|
806
|
+
/**
|
|
807
|
+
* Every encoder a codec file exports has the decoder its name implies, exported by the same file, and every decoder the encoder. A name is an encoder or a decoder when it fits that template; other exports are not codecs and are not judged. A half re-exported from another file counts, and is reported where it is declared.
|
|
808
|
+
*
|
|
809
|
+
* It checks that the counterpart is exported, not that the two round-trip: that is a property test of the repository's own.
|
|
810
|
+
*/
|
|
811
|
+
export declare const codecPairs: CheckFunction<CodecPairsOptions>;
|
|
812
|
+
//#endregion
|
|
744
813
|
//#region src/checks/command-types.d.ts
|
|
745
814
|
/**
|
|
746
815
|
* The last names of the generics that turn a schema into its type, used when the options name none: `z.infer`, `z.input`, `z.output`, `z.TypeOf` and Valibot's `InferInput` and `InferOutput`.
|
|
@@ -765,6 +834,18 @@ export declare const PRESET_COMMIT_TYPES: readonly string[];
|
|
|
765
834
|
*/
|
|
766
835
|
export declare const commitTypes: CheckFunction<CommitTypesOptions>;
|
|
767
836
|
//#endregion
|
|
837
|
+
//#region src/checks/derived-types.d.ts
|
|
838
|
+
/**
|
|
839
|
+
* The last names that count as inference when the options name none: those of `command-types`, Drizzle's `InferSelectModel` and `InferInsertModel` generics, and the `$inferSelect` and `$inferInsert` members of a Drizzle table, read as `typeof table.$inferSelect`.
|
|
840
|
+
*/
|
|
841
|
+
export declare const DEFAULT_DERIVED_TYPE_INFERENCES: readonly string[];
|
|
842
|
+
/**
|
|
843
|
+
* For each pair, every exported interface and type alias of its type files is derived from a schema declared in its schema files: somewhere in its definition an inference (a generic in `inferences`, such as `z.infer` or `InferSelectModel`) is applied to `typeof schema`, or an inference member is read from it (`typeof table.$inferSelect`).
|
|
844
|
+
*
|
|
845
|
+
* The definition is followed through aliases and interfaces without type parameters, in any file, and through the arguments of other generics, intersections, unions whose members are all derived (`null` and `undefined` aside), arrays, type operators and indexed access. A type literal, and a schema passed to a generic that is not an inference, are written by hand.
|
|
846
|
+
*/
|
|
847
|
+
export declare const derivedTypes: CheckFunction<DerivedTypesOptions>;
|
|
848
|
+
//#endregion
|
|
768
849
|
//#region src/checks/dockerfile-package-manager.d.ts
|
|
769
850
|
/**
|
|
770
851
|
* Every pin of the package manager that `packageManager` names, in each Dockerfile, is the version `packageManager` names, with any `+sha` integrity suffix ignored on both sides. Pins of other package managers are not the workspace's package manager and are left alone.
|
|
@@ -1275,4 +1356,4 @@ export declare function proveExhaustive(input: {
|
|
|
1275
1356
|
readonly compilerOptions?: CompilerOptions;
|
|
1276
1357
|
}): ExhaustivenessProof;
|
|
1277
1358
|
//#endregion
|
|
1278
|
-
export type { AggregateMappersOptions, BranchRules, CaseRemoval, CheckContext, CheckFunction, CheckName, CheckOptionsByName, CheckResult, ChecksConfig, CommandTypesOptions, CommitTypesOptions, ConformanceConfig, DeployDirectory, DeploySelector, DeployToolAdapter, DeployToolName, DiscoveredPackage, DockerfilePackageManagerOptions, EslintOptions, EslintRequiredSeverity, EslintSample, ExhaustivenessProof, GeneratorAdapter, GeneratorName, GitHubCheckContext, GitHubCheckFunction, GitHubClient, GitHubClientOptions, ImportGraphOptions, InstructionSymlinksOptions, Job, LayoutCheckContext, LayoutCheckFunction, MigrationsDirectoryOptions, PermissionAccess, Permissions, PinningLevel, RegisteredCheck, RepositorySettings, RepositorySlug, RunChecksOptions, RunResult, RunsOn, SettingsMergeMethodsOptions, SettingsOptions, SettingsRequiredChecksOptions, SettingsReviewThreadResolutionOptions, SingleStorybookOptions, SourceLocation, Step, TypeErrorReport, UsesReference, Violation, Workflow, WorkflowActionPinningOptions, WorkflowCredentialsOptions, WorkflowJobOrderingOptions, WorkflowMergeGroupOptions, WorkflowRepositoryDispatchOptions, WorkflowRunnerResolutionOptions, WorkflowSelection, WorkflowSkippableJobsOptions, WorkflowUpdateBotCooldownOptions, WorkflowVersionSingleSourceOptions, WorkspacePackage };
|
|
1359
|
+
export type { AggregateMappersOptions, BranchRules, CaseRemoval, CheckContext, CheckFunction, CheckName, CheckOptionsByName, CheckResult, ChecksConfig, CodecPairsOptions, CommandTypesOptions, CommitTypesOptions, ConformanceConfig, DeployDirectory, DeploySelector, DeployToolAdapter, DeployToolName, DerivedTypesOptions, DerivedTypesPair, DiscoveredPackage, DockerfilePackageManagerOptions, EslintOptions, EslintRequiredSeverity, EslintSample, ExhaustivenessProof, GeneratorAdapter, GeneratorName, GitHubCheckContext, GitHubCheckFunction, GitHubClient, GitHubClientOptions, ImportGraphOptions, InstructionSymlinksOptions, Job, LayoutCheckContext, LayoutCheckFunction, MigrationsDirectoryOptions, PermissionAccess, Permissions, PinningLevel, RegisteredCheck, RepositorySettings, RepositorySlug, RunChecksOptions, RunResult, RunsOn, SettingsMergeMethodsOptions, SettingsOptions, SettingsRequiredChecksOptions, SettingsReviewThreadResolutionOptions, SingleStorybookOptions, SourceLocation, Step, TypeErrorReport, UsesReference, Violation, Workflow, WorkflowActionPinningOptions, WorkflowCredentialsOptions, WorkflowJobOrderingOptions, WorkflowMergeGroupOptions, WorkflowRepositoryDispatchOptions, WorkflowRunnerResolutionOptions, WorkflowSelection, WorkflowSkippableJobsOptions, WorkflowUpdateBotCooldownOptions, WorkflowVersionSingleSourceOptions, WorkspacePackage };
|
package/dist/index.d.ts
CHANGED
|
@@ -376,6 +376,31 @@ interface AggregateMappersOptions {
|
|
|
376
376
|
*/
|
|
377
377
|
readonly tsConfig?: string;
|
|
378
378
|
}
|
|
379
|
+
/**
|
|
380
|
+
* Options of the `codec-pairs` check: every encoder a codec file exports has a decoder it also exports, and every decoder an encoder.
|
|
381
|
+
*/
|
|
382
|
+
interface CodecPairsOptions {
|
|
383
|
+
/**
|
|
384
|
+
* Globs of the codec files, relative to the directory the checks run in. Each file is judged on its own exports, re-exports included.
|
|
385
|
+
*/
|
|
386
|
+
readonly codecs: readonly string[];
|
|
387
|
+
/**
|
|
388
|
+
* The name of an encoder, with `{name}` standing for the name it shares with its decoder, such as `encode{name}` or `{name}Encoder`. `{name}` appears exactly once, beside other text, and is the only placeholder.
|
|
389
|
+
*/
|
|
390
|
+
readonly encoder: string;
|
|
391
|
+
/**
|
|
392
|
+
* The name of a decoder, in the same form as `encoder` and different from it.
|
|
393
|
+
*/
|
|
394
|
+
readonly decoder: string;
|
|
395
|
+
/**
|
|
396
|
+
* Names of exported encoders and decoders that need no counterpart, such as an encoder for a format that is only ever written.
|
|
397
|
+
*/
|
|
398
|
+
readonly exclude?: readonly string[];
|
|
399
|
+
/**
|
|
400
|
+
* The tsconfig that supplies compiler options and module resolution; `tsconfig.json` when omitted.
|
|
401
|
+
*/
|
|
402
|
+
readonly tsConfig?: string;
|
|
403
|
+
}
|
|
379
404
|
/**
|
|
380
405
|
* Options of the `command-types` check: every command type a file exports is derived from a schema.
|
|
381
406
|
*/
|
|
@@ -397,6 +422,40 @@ interface CommandTypesOptions {
|
|
|
397
422
|
*/
|
|
398
423
|
readonly tsConfig?: string;
|
|
399
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* A set of schema files and the files whose exported types must be derived from those schemas.
|
|
427
|
+
*/
|
|
428
|
+
interface DerivedTypesPair {
|
|
429
|
+
/**
|
|
430
|
+
* Globs of the files that declare the schemas, relative to the directory the checks run in.
|
|
431
|
+
*/
|
|
432
|
+
readonly schemas: readonly string[];
|
|
433
|
+
/**
|
|
434
|
+
* Globs of the files whose exported interfaces and type aliases must be derived from a schema declared in `schemas`.
|
|
435
|
+
*/
|
|
436
|
+
readonly types: readonly string[];
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Options of the `derived-types` check: every type a file exports is derived from a schema of its pair.
|
|
440
|
+
*/
|
|
441
|
+
interface DerivedTypesOptions {
|
|
442
|
+
/**
|
|
443
|
+
* The schema files and the type files that must derive from them. Each type file is judged against the schemas of every pair that lists it.
|
|
444
|
+
*/
|
|
445
|
+
readonly pairs: readonly DerivedTypesPair[];
|
|
446
|
+
/**
|
|
447
|
+
* Names of exported types that are deliberately written by hand.
|
|
448
|
+
*/
|
|
449
|
+
readonly exclude?: readonly string[];
|
|
450
|
+
/**
|
|
451
|
+
* The last names of the generics that turn a schema into its type, and of the members that hold it, such as `infer` in `z.infer<typeof schema>` and `$inferSelect` in `typeof table.$inferSelect`. `infer`, `input`, `output`, `TypeOf`, `InferInput`, `InferOutput`, `InferSelectModel`, `InferInsertModel`, `$inferSelect` and `$inferInsert` when omitted.
|
|
452
|
+
*/
|
|
453
|
+
readonly inferences?: readonly string[];
|
|
454
|
+
/**
|
|
455
|
+
* The tsconfig that supplies compiler options and module resolution; `tsconfig.json` when omitted.
|
|
456
|
+
*/
|
|
457
|
+
readonly tsConfig?: string;
|
|
458
|
+
}
|
|
400
459
|
/**
|
|
401
460
|
* Options shared by the checks that cruise the workspace's import graph.
|
|
402
461
|
*/
|
|
@@ -703,7 +762,9 @@ type SettingsReviewThreadResolutionOptions = SettingsOptions;
|
|
|
703
762
|
*/
|
|
704
763
|
interface CheckOptionsByName {
|
|
705
764
|
readonly "aggregate-mappers": AggregateMappersOptions;
|
|
765
|
+
readonly "codec-pairs": CodecPairsOptions;
|
|
706
766
|
readonly "command-types": CommandTypesOptions;
|
|
767
|
+
readonly "derived-types": DerivedTypesOptions;
|
|
707
768
|
readonly "import-uphill": ImportGraphOptions;
|
|
708
769
|
readonly "import-rank-skip": ImportGraphOptions;
|
|
709
770
|
readonly "import-cross-slice": ImportGraphOptions;
|
|
@@ -741,6 +802,14 @@ type CheckName = keyof CheckOptionsByName;
|
|
|
741
802
|
*/
|
|
742
803
|
export declare const aggregateMappers: CheckFunction<AggregateMappersOptions>;
|
|
743
804
|
//#endregion
|
|
805
|
+
//#region src/checks/codec-pairs.d.ts
|
|
806
|
+
/**
|
|
807
|
+
* Every encoder a codec file exports has the decoder its name implies, exported by the same file, and every decoder the encoder. A name is an encoder or a decoder when it fits that template; other exports are not codecs and are not judged. A half re-exported from another file counts, and is reported where it is declared.
|
|
808
|
+
*
|
|
809
|
+
* It checks that the counterpart is exported, not that the two round-trip: that is a property test of the repository's own.
|
|
810
|
+
*/
|
|
811
|
+
export declare const codecPairs: CheckFunction<CodecPairsOptions>;
|
|
812
|
+
//#endregion
|
|
744
813
|
//#region src/checks/command-types.d.ts
|
|
745
814
|
/**
|
|
746
815
|
* The last names of the generics that turn a schema into its type, used when the options name none: `z.infer`, `z.input`, `z.output`, `z.TypeOf` and Valibot's `InferInput` and `InferOutput`.
|
|
@@ -765,6 +834,18 @@ export declare const PRESET_COMMIT_TYPES: readonly string[];
|
|
|
765
834
|
*/
|
|
766
835
|
export declare const commitTypes: CheckFunction<CommitTypesOptions>;
|
|
767
836
|
//#endregion
|
|
837
|
+
//#region src/checks/derived-types.d.ts
|
|
838
|
+
/**
|
|
839
|
+
* The last names that count as inference when the options name none: those of `command-types`, Drizzle's `InferSelectModel` and `InferInsertModel` generics, and the `$inferSelect` and `$inferInsert` members of a Drizzle table, read as `typeof table.$inferSelect`.
|
|
840
|
+
*/
|
|
841
|
+
export declare const DEFAULT_DERIVED_TYPE_INFERENCES: readonly string[];
|
|
842
|
+
/**
|
|
843
|
+
* For each pair, every exported interface and type alias of its type files is derived from a schema declared in its schema files: somewhere in its definition an inference (a generic in `inferences`, such as `z.infer` or `InferSelectModel`) is applied to `typeof schema`, or an inference member is read from it (`typeof table.$inferSelect`).
|
|
844
|
+
*
|
|
845
|
+
* The definition is followed through aliases and interfaces without type parameters, in any file, and through the arguments of other generics, intersections, unions whose members are all derived (`null` and `undefined` aside), arrays, type operators and indexed access. A type literal, and a schema passed to a generic that is not an inference, are written by hand.
|
|
846
|
+
*/
|
|
847
|
+
export declare const derivedTypes: CheckFunction<DerivedTypesOptions>;
|
|
848
|
+
//#endregion
|
|
768
849
|
//#region src/checks/dockerfile-package-manager.d.ts
|
|
769
850
|
/**
|
|
770
851
|
* Every pin of the package manager that `packageManager` names, in each Dockerfile, is the version `packageManager` names, with any `+sha` integrity suffix ignored on both sides. Pins of other package managers are not the workspace's package manager and are left alone.
|
|
@@ -1275,4 +1356,4 @@ export declare function proveExhaustive(input: {
|
|
|
1275
1356
|
readonly compilerOptions?: CompilerOptions;
|
|
1276
1357
|
}): ExhaustivenessProof;
|
|
1277
1358
|
//#endregion
|
|
1278
|
-
export type { AggregateMappersOptions, BranchRules, CaseRemoval, CheckContext, CheckFunction, CheckName, CheckOptionsByName, CheckResult, ChecksConfig, CommandTypesOptions, CommitTypesOptions, ConformanceConfig, DeployDirectory, DeploySelector, DeployToolAdapter, DeployToolName, DiscoveredPackage, DockerfilePackageManagerOptions, EslintOptions, EslintRequiredSeverity, EslintSample, ExhaustivenessProof, GeneratorAdapter, GeneratorName, GitHubCheckContext, GitHubCheckFunction, GitHubClient, GitHubClientOptions, ImportGraphOptions, InstructionSymlinksOptions, Job, LayoutCheckContext, LayoutCheckFunction, MigrationsDirectoryOptions, PermissionAccess, Permissions, PinningLevel, RegisteredCheck, RepositorySettings, RepositorySlug, RunChecksOptions, RunResult, RunsOn, SettingsMergeMethodsOptions, SettingsOptions, SettingsRequiredChecksOptions, SettingsReviewThreadResolutionOptions, SingleStorybookOptions, SourceLocation, Step, TypeErrorReport, UsesReference, Violation, Workflow, WorkflowActionPinningOptions, WorkflowCredentialsOptions, WorkflowJobOrderingOptions, WorkflowMergeGroupOptions, WorkflowRepositoryDispatchOptions, WorkflowRunnerResolutionOptions, WorkflowSelection, WorkflowSkippableJobsOptions, WorkflowUpdateBotCooldownOptions, WorkflowVersionSingleSourceOptions, WorkspacePackage };
|
|
1359
|
+
export type { AggregateMappersOptions, BranchRules, CaseRemoval, CheckContext, CheckFunction, CheckName, CheckOptionsByName, CheckResult, ChecksConfig, CodecPairsOptions, CommandTypesOptions, CommitTypesOptions, ConformanceConfig, DeployDirectory, DeploySelector, DeployToolAdapter, DeployToolName, DerivedTypesOptions, DerivedTypesPair, DiscoveredPackage, DockerfilePackageManagerOptions, EslintOptions, EslintRequiredSeverity, EslintSample, ExhaustivenessProof, GeneratorAdapter, GeneratorName, GitHubCheckContext, GitHubCheckFunction, GitHubClient, GitHubClientOptions, ImportGraphOptions, InstructionSymlinksOptions, Job, LayoutCheckContext, LayoutCheckFunction, MigrationsDirectoryOptions, PermissionAccess, Permissions, PinningLevel, RegisteredCheck, RepositorySettings, RepositorySlug, RunChecksOptions, RunResult, RunsOn, SettingsMergeMethodsOptions, SettingsOptions, SettingsRequiredChecksOptions, SettingsReviewThreadResolutionOptions, SingleStorybookOptions, SourceLocation, Step, TypeErrorReport, UsesReference, Violation, Workflow, WorkflowActionPinningOptions, WorkflowCredentialsOptions, WorkflowJobOrderingOptions, WorkflowMergeGroupOptions, WorkflowRepositoryDispatchOptions, WorkflowRunnerResolutionOptions, WorkflowSelection, WorkflowSkippableJobsOptions, WorkflowUpdateBotCooldownOptions, WorkflowVersionSingleSourceOptions, WorkspacePackage };
|