Open samuelstroschein opened 5 days ago
@loris.sigrist @martin.lysk1
loadProject2
. pushback if you think it's a distraction now. run
function according to the data primitive e.g. lintBundle
, lintMessage
, lintVariant
, lintCode
, lintDesign
, etc.Great writeup - We will adopt consider this structure.
This describes what we briefly discussed with - we need lints for different levels (project, bundles, messages, variants) or even whole different entities (figma nodes)
One note:
I would keep one lint rule, one function to avoid situations like "i want to disable the code lint of lint rule X but keep the bundle lint"
If a message should always contain one run method (and i agree 100%) we could keep the structure and give each lint a type enum that discloses the expected parameter of the the function:
enum LintRuleType {
Bundle = "Bundle",
Message = "Message",
Variant = "Variant",
Code = "Code",
Design = "Design"
}
// Base LintRule type with discriminated union for each rule type
type LintRule =
| { id: string, type: LintRuleType.Bundle, run: (bundle: any, settings: any, report: any) => any }
| { id: string, type: LintRuleType.Message, run: (message: any, settings: any, report: any) => any }
| { id: string, type: LintRuleType.Variant, run: (variant: any, settings: any, report: any) => any }
| { id: string, type: LintRuleType.Code, run: (sourceFile: any, settings: any, report: any) => any }
| { id: string, type: LintRuleType.Design, run: (design: any, settings: any, report: any) => any }
// Example implementation of a lint rule
const exampleLintRule: LintRule = {
id: "example-rule",
type: LintRuleType.Code,
run: (sourceFile, settings, report) => {
// Implement the linting logic for code
console.log("Linting code:", sourceFile);
}
}
Another thought here - we could even use the id pattern to discriminate the lint type - but my type gymnastics end here @loris.sigrist
Any downsides i miss?
@martin.lysk1 your proposal is identical to mine. we both use union types except that you discriminate via type
and overload via run
.
thoughts:
type
is more natural than codeLint
etc. 👍 propsal:
get rid of the enum :D please confirm if you agree
type LintRule =
| { id: string, type: "bundle", run: (bundle: any, settings: any, report: any) => any }
| { id: string, type: "message", run: (message: any, settings: any, report: any) => any }
| { id: string, type: "variant", run: (variant: any, settings: any, report: any) => any }
| { id: string, type: "code", run: (sourceFile: any, settings: any, report: any) => any }
| { id: string, type: "design", run: (design: any, settings: any, report: any) => any }
Call with @martin.lysk1 and @loris.sigrist agreements
1. which node is a lint report attached to?
-> lint reports only provide bundleId|messageId|variantId
locale
as lint report property? key
key
generalizes across all lint rules. allowing arbitrary properties limits the possibilities for us to add properties as we need. how to create, update, delete
-> Updating bundles yes. Create and delete in v2.
machine translate
-> just use inlang/rpc
directly in the missing translation lint rule until machine translate plugin api exists
@martin.lysk1 @loris.sigrist please use 👍 to acknowledge that you read this and agree
Context
@martin.lysk1 and @loris.sigrist have been working on a new API for lint rules that is a breaking change and will foreseeably get a breaking change again. Plus, the API will be slow (maybe fast enough for MESDK-137 though!)
Why does the current and future lint API lead to recurring breaking changes?
The APIs are designed around a data structure. Any change in the data structure leads to a breaking change in the lint API.
For example, the current API lints on the messages primitive. The new proposal lints on message bundles. The result is that the entire linting system breaks (and is thrown away…). The data structure leaks into everything a lint rule does. From the id, to execution functions, to scheduling.
Why are the APIs slow?
Disclaimer: It might be fast enough to fulfill MESDK-137.
Passing the top level node (MessageBundles) to a lint rule entails that a lint rule:
Potential solution
Have one lint rule API with different functions for different data primitives.
Aka rename
run
tolintBundle
and remove the hardcoded data primitive type from the idbundleLintRule.{namespace}.{key}
->lintRule.{namespace}.{key}
What we need today:
We can extend the lint rule function in the future (if the need arises!)
Further notes:
report
function might or might not differ between the different lint functions. TBDConsidered alternatives
Expose the query (get) APIs.