@gd-kirie/alint-config 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -74
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,79 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
interface AlintConfig {
|
|
4
|
-
plugins?: PluginDefinition[];
|
|
5
|
-
rules?: Record<string, RuleConfigEntry>;
|
|
6
|
-
}
|
|
7
|
-
interface DiagnosticDescriptor {
|
|
8
|
-
evidence?: unknown;
|
|
9
|
-
filePath?: string;
|
|
10
|
-
loc?: DiagnosticLocation;
|
|
11
|
-
message: string;
|
|
12
|
-
}
|
|
13
|
-
interface DiagnosticLocation {
|
|
14
|
-
end?: SourcePosition;
|
|
15
|
-
start: SourcePosition;
|
|
16
|
-
}
|
|
17
|
-
interface InferenceUsageRecord {
|
|
18
|
-
inputTokens?: number;
|
|
19
|
-
modelId: string;
|
|
20
|
-
outputTokens?: number;
|
|
21
|
-
providerId: string;
|
|
22
|
-
totalTokens?: number;
|
|
23
|
-
}
|
|
24
|
-
interface PluginDefinition {
|
|
25
|
-
rules: Record<string, RuleDefinition>;
|
|
26
|
-
scope: string;
|
|
27
|
-
}
|
|
28
|
-
type RuleConfigEntry = [RuleSeverity] | RuleSeverity;
|
|
29
|
-
interface RuleContext {
|
|
30
|
-
metering?: {
|
|
31
|
-
recordUsage: (usage: InferenceUsageRecord) => void;
|
|
32
|
-
};
|
|
33
|
-
model: () => Promise<ResolvedModel>;
|
|
34
|
-
report: (diagnostic: DiagnosticDescriptor) => void;
|
|
35
|
-
}
|
|
36
|
-
interface RuleDefinition {
|
|
37
|
-
cache?: boolean | {
|
|
38
|
-
level?: "target";
|
|
39
|
-
};
|
|
40
|
-
create: (context: RuleContext) => RuleHandlers;
|
|
41
|
-
model?: ModelRequirement;
|
|
42
|
-
}
|
|
43
|
-
interface RuleHandlers {
|
|
44
|
-
onFile?: (file: SourceFile) => Awaitable<void>;
|
|
45
|
-
}
|
|
46
|
-
type RuleSeverity = "error" | "off" | "warn";
|
|
47
|
-
interface SourceFile {
|
|
48
|
-
language: "javascript" | "typescript" | "unknown";
|
|
49
|
-
lines: string[];
|
|
50
|
-
path: string;
|
|
51
|
-
text: string;
|
|
52
|
-
}
|
|
53
|
-
interface SourcePosition {
|
|
54
|
-
column: number;
|
|
55
|
-
line: number;
|
|
56
|
-
}
|
|
57
|
-
interface ResolvedModel {
|
|
58
|
-
id: string;
|
|
59
|
-
provider: {
|
|
60
|
-
endpoint: string;
|
|
61
|
-
headers?: Record<string, string>;
|
|
62
|
-
id: string;
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
interface ModelRequirement {
|
|
66
|
-
capabilities?: string[];
|
|
67
|
-
minContextWindow?: number;
|
|
68
|
-
params?: Record<string, unknown>;
|
|
69
|
-
size?: string;
|
|
70
|
-
}
|
|
71
|
-
//#endregion
|
|
1
|
+
import { AlintConfig, AlintConfig as AlintConfig$1, Awaitable, DiagnosticDescriptor, DiagnosticLocation, ModelRequirement, PluginDefinition, PluginDefinition as PluginDefinition$1, ResolvedModel, RuleConfigEntry, RuleContext, RuleDefinition, RuleDefinition as RuleDefinition$1, RuleHandlers, RuleInferenceUsageRecord as InferenceUsageRecord, RuleSeverity, SourceFile, SourcePosition } from "@alint-js/core";
|
|
2
|
+
|
|
72
3
|
//#region src/config.d.ts
|
|
73
|
-
declare const gdKirieAlintConfig: AlintConfig;
|
|
4
|
+
declare const gdKirieAlintConfig: AlintConfig$1;
|
|
74
5
|
//#endregion
|
|
75
6
|
//#region src/plugin.d.ts
|
|
76
|
-
declare const gdKirieAlintPlugin: PluginDefinition;
|
|
7
|
+
declare const gdKirieAlintPlugin: PluginDefinition$1;
|
|
77
8
|
//#endregion
|
|
78
9
|
//#region src/rules/no-stringified-rethrow.d.ts
|
|
79
10
|
interface ErrorWrappingReviewFinding {
|
|
@@ -81,7 +12,7 @@ interface ErrorWrappingReviewFinding {
|
|
|
81
12
|
line: number;
|
|
82
13
|
message?: string;
|
|
83
14
|
}
|
|
84
|
-
declare const noStringifiedRethrowRule: RuleDefinition;
|
|
15
|
+
declare const noStringifiedRethrowRule: RuleDefinition$1;
|
|
85
16
|
//#endregion
|
|
86
17
|
export { type AlintConfig, type Awaitable, type DiagnosticDescriptor, type DiagnosticLocation, type ErrorWrappingReviewFinding, type InferenceUsageRecord, type ModelRequirement, type PluginDefinition, type ResolvedModel, type RuleConfigEntry, type RuleContext, type RuleDefinition, type RuleHandlers, type RuleSeverity, type SourceFile, type SourcePosition, gdKirieAlintConfig as default, gdKirieAlintConfig, gdKirieAlintPlugin, noStringifiedRethrowRule };
|
|
87
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/config.ts","../src/plugin.ts","../src/rules/no-stringified-rethrow.ts"],"mappings":";;;cAIa,kBAAA,EAAoB,aAAA;;;cCApB,kBAAA,EAAoB,kBAAA;;;UCChB,0BAAA;EACf,QAAA;EACA,IAAA;EACA,OAAA;AAAA;AAAA,cAOW,wBAAA,EAA0B,gBAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { defineConfig, definePlugin, defineRule } from "@alint-js/core";
|
|
1
2
|
import { generateText } from "xsai";
|
|
2
3
|
//#region src/rules/no-stringified-rethrow.ts
|
|
3
|
-
const noStringifiedRethrowRule = { create: (ctx) => ({ async
|
|
4
|
+
const noStringifiedRethrowRule = defineRule({ create: (ctx) => ({ async onTargetFile({ file }) {
|
|
4
5
|
const findings = await reviewStringifiedRethrows(file, await ctx.model(), ctx.metering);
|
|
5
6
|
for (const finding of findings) ctx.report({
|
|
6
7
|
evidence: finding.evidence,
|
|
@@ -11,7 +12,7 @@ const noStringifiedRethrowRule = { create: (ctx) => ({ async onFile(file) {
|
|
|
11
12
|
} },
|
|
12
13
|
message: finding.message ?? "Do not stringify and rethrow caught errors; preserve the original error as cause."
|
|
13
14
|
});
|
|
14
|
-
} }) };
|
|
15
|
+
} }) });
|
|
15
16
|
async function reviewStringifiedRethrows(file, model, usage) {
|
|
16
17
|
const response = await generateText({
|
|
17
18
|
baseURL: model.provider.endpoint,
|
|
@@ -61,7 +62,6 @@ function isReviewFinding(value) {
|
|
|
61
62
|
return typeof finding.line === "number" && Number.isInteger(finding.line) && finding.line > 0;
|
|
62
63
|
}
|
|
63
64
|
function recordUsage(metering, model, response) {
|
|
64
|
-
if (!metering) return;
|
|
65
65
|
metering.recordUsage({
|
|
66
66
|
inputTokens: response.usage.inputTokens,
|
|
67
67
|
modelId: model.id,
|
|
@@ -72,16 +72,13 @@ function recordUsage(metering, model, response) {
|
|
|
72
72
|
}
|
|
73
73
|
//#endregion
|
|
74
74
|
//#region src/plugin.ts
|
|
75
|
-
const gdKirieAlintPlugin = {
|
|
76
|
-
rules: { "no-stringified-rethrow": noStringifiedRethrowRule },
|
|
77
|
-
scope: "@gd-kirie"
|
|
78
|
-
};
|
|
75
|
+
const gdKirieAlintPlugin = definePlugin({ rules: { "no-stringified-rethrow": noStringifiedRethrowRule } });
|
|
79
76
|
//#endregion
|
|
80
77
|
//#region src/config.ts
|
|
81
|
-
const gdKirieAlintConfig = {
|
|
82
|
-
plugins:
|
|
78
|
+
const gdKirieAlintConfig = defineConfig([{
|
|
79
|
+
plugins: { "@gd-kirie": gdKirieAlintPlugin },
|
|
83
80
|
rules: { "@gd-kirie/no-stringified-rethrow": "warn" }
|
|
84
|
-
};
|
|
81
|
+
}]);
|
|
85
82
|
//#endregion
|
|
86
83
|
export { gdKirieAlintConfig as default, gdKirieAlintConfig, gdKirieAlintPlugin, noStringifiedRethrowRule };
|
|
87
84
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/rules/no-stringified-rethrow.ts","../src/plugin.ts","../src/config.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/rules/no-stringified-rethrow.ts","../src/plugin.ts","../src/config.ts"],"sourcesContent":["import type { ResolvedModel, RuleContext, RuleDefinition, SourceFile } from \"@alint-js/core\";\nimport { defineRule } from \"@alint-js/core\";\nimport type { GenerateTextResult } from \"xsai\";\nimport { generateText } from \"xsai\";\n\nexport interface ErrorWrappingReviewFinding {\n evidence?: unknown;\n line: number;\n message?: string;\n}\n\ninterface ReviewResponse {\n findings?: ErrorWrappingReviewFinding[];\n}\n\nexport const noStringifiedRethrowRule: RuleDefinition = defineRule({\n create: (ctx) => ({\n async onTargetFile({ file }) {\n const model = await ctx.model();\n const findings = await reviewStringifiedRethrows(file, model, ctx.metering);\n\n for (const finding of findings) {\n ctx.report({\n evidence: finding.evidence,\n filePath: file.path,\n loc: {\n start: {\n column: 0,\n line: finding.line,\n },\n },\n message:\n finding.message ??\n \"Do not stringify and rethrow caught errors; preserve the original error as cause.\",\n });\n }\n },\n }),\n});\n\nasync function reviewStringifiedRethrows(\n file: SourceFile,\n model: ResolvedModel,\n usage: RuleContext[\"metering\"],\n): Promise<ErrorWrappingReviewFinding[]> {\n const response = await generateText({\n baseURL: model.provider.endpoint,\n headers: model.provider.headers,\n messages: createReviewMessages(file),\n model: model.id,\n response_format: {\n type: \"json_object\",\n },\n temperature: 0,\n });\n const content = response.text;\n\n if (typeof content !== \"string\") {\n throw new Error(\"alint model response did not include message content.\");\n }\n\n recordUsage(usage, model, response);\n\n const result = JSON.parse(content) as ReviewResponse;\n\n if (!Array.isArray(result.findings)) {\n return [];\n }\n\n return result.findings.filter(isReviewFinding);\n}\n\nfunction createReviewMessages(\n file: SourceFile,\n): Array<{ content: string; role: \"system\" | \"user\" }> {\n return [\n {\n content: [\n \"You are reviewing one JavaScript or TypeScript file.\",\n \"\",\n \"Task:\",\n \"Find catch blocks that stringify, format, or otherwise collapse the caught error into a message string before throwing a new error, without preserving the original error as the error cause.\",\n \"\",\n \"Report only cases where the original caught error is not preserved through `cause` or an equivalent custom error cause field.\",\n \"Do not report code that throws `new Error(message, { cause: error })`.\",\n \"Do not report custom error classes that pass or store the caught error as cause.\",\n \"Do not report code that logs an error and rethrows the same original error.\",\n \"\",\n \"Return JSON only with this shape:\",\n '{\"findings\":[{\"line\":1,\"message\":\"short diagnostic\",\"evidence\":{\"reason\":\"short reason\"}}]}',\n \"Use the line number of the throw statement.\",\n \"Return an empty findings array when there is no issue.\",\n ].join(\"\\n\"),\n role: \"system\",\n },\n {\n content: `File: ${file.path}\\n\\n${formatSourceWithLineNumbers(file.text)}`,\n role: \"user\",\n },\n ];\n}\n\nfunction formatSourceWithLineNumbers(source: string): string {\n return source\n .split(\"\\n\")\n .map((line, index) => `${index + 1} | ${line}`)\n .join(\"\\n\");\n}\n\nfunction isReviewFinding(value: unknown): value is ErrorWrappingReviewFinding {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const finding = value as Partial<ErrorWrappingReviewFinding>;\n\n return typeof finding.line === \"number\" && Number.isInteger(finding.line) && finding.line > 0;\n}\n\nfunction recordUsage(\n metering: RuleContext[\"metering\"],\n model: ResolvedModel,\n response: GenerateTextResult,\n): void {\n metering.recordUsage({\n inputTokens: response.usage.inputTokens,\n modelId: model.id,\n outputTokens: response.usage.outputTokens,\n providerId: model.provider.id,\n totalTokens: response.usage.totalTokens,\n });\n}\n","import type { PluginDefinition } from \"@alint-js/core\";\nimport { definePlugin } from \"@alint-js/core\";\nimport { noStringifiedRethrowRule } from \"./rules/no-stringified-rethrow\";\n\nexport const gdKirieAlintPlugin: PluginDefinition = definePlugin({\n rules: {\n \"no-stringified-rethrow\": noStringifiedRethrowRule,\n },\n});\n","import type { AlintConfig } from \"@alint-js/core\";\nimport { defineConfig } from \"@alint-js/core\";\nimport { gdKirieAlintPlugin } from \"./plugin\";\n\nexport const gdKirieAlintConfig: AlintConfig = defineConfig([\n {\n plugins: {\n \"@gd-kirie\": gdKirieAlintPlugin,\n },\n rules: {\n \"@gd-kirie/no-stringified-rethrow\": \"warn\",\n },\n },\n]);\n"],"mappings":";;;AAeA,MAAa,2BAA2C,WAAW,EACjE,SAAS,SAAS,EAChB,MAAM,aAAa,EAAE,QAAQ;CAE3B,MAAM,WAAW,MAAM,0BAA0B,MAAM,MADnC,IAAI,MAAM,GACgC,IAAI,QAAQ;CAE1E,KAAK,MAAM,WAAW,UACpB,IAAI,OAAO;EACT,UAAU,QAAQ;EAClB,UAAU,KAAK;EACf,KAAK,EACH,OAAO;GACL,QAAQ;GACR,MAAM,QAAQ;EAChB,EACF;EACA,SACE,QAAQ,WACR;CACJ,CAAC;AAEL,EACF,GACF,CAAC;AAED,eAAe,0BACb,MACA,OACA,OACuC;CACvC,MAAM,WAAW,MAAM,aAAa;EAClC,SAAS,MAAM,SAAS;EACxB,SAAS,MAAM,SAAS;EACxB,UAAU,qBAAqB,IAAI;EACnC,OAAO,MAAM;EACb,iBAAiB,EACf,MAAM,cACR;EACA,aAAa;CACf,CAAC;CACD,MAAM,UAAU,SAAS;CAEzB,IAAI,OAAO,YAAY,UACrB,MAAM,IAAI,MAAM,uDAAuD;CAGzE,YAAY,OAAO,OAAO,QAAQ;CAElC,MAAM,SAAS,KAAK,MAAM,OAAO;CAEjC,IAAI,CAAC,MAAM,QAAQ,OAAO,QAAQ,GAChC,OAAO,CAAC;CAGV,OAAO,OAAO,SAAS,OAAO,eAAe;AAC/C;AAEA,SAAS,qBACP,MACqD;CACrD,OAAO,CACL;EACE,SAAS;GACP;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,CAAC,CAAC,KAAK,IAAI;EACX,MAAM;CACR,GACA;EACE,SAAS,SAAS,KAAK,KAAK,MAAM,4BAA4B,KAAK,IAAI;EACvE,MAAM;CACR,CACF;AACF;AAEA,SAAS,4BAA4B,QAAwB;CAC3D,OAAO,OACJ,MAAM,IAAI,CAAC,CACX,KAAK,MAAM,UAAU,GAAG,QAAQ,EAAE,KAAK,MAAM,CAAC,CAC9C,KAAK,IAAI;AACd;AAEA,SAAS,gBAAgB,OAAqD;CAC5E,IAAI,CAAC,SAAS,OAAO,UAAU,UAC7B,OAAO;CAGT,MAAM,UAAU;CAEhB,OAAO,OAAO,QAAQ,SAAS,YAAY,OAAO,UAAU,QAAQ,IAAI,KAAK,QAAQ,OAAO;AAC9F;AAEA,SAAS,YACP,UACA,OACA,UACM;CACN,SAAS,YAAY;EACnB,aAAa,SAAS,MAAM;EAC5B,SAAS,MAAM;EACf,cAAc,SAAS,MAAM;EAC7B,YAAY,MAAM,SAAS;EAC3B,aAAa,SAAS,MAAM;CAC9B,CAAC;AACH;;;AC/HA,MAAa,qBAAuC,aAAa,EAC/D,OAAO,EACL,0BAA0B,yBAC5B,EACF,CAAC;;;ACJD,MAAa,qBAAkC,aAAa,CAC1D;CACE,SAAS,EACP,aAAa,mBACf;CACA,OAAO,EACL,oCAAoC,OACtC;AACF,CACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gd-kirie/alint-config",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"README.md"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
+
"@alint-js/core": "^0.0.38",
|
|
23
24
|
"xsai": "^0.5.0-beta.6"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|