@@ -258,16 +258,38 @@ interface PluginOptions extends Options, NamespaceOptions {}
258258interface PluginContext {
259259 fix : boolean ;
260260}
261+
262+ // Extracted from stylelint
263+ type StylelintRuleBase < P = any , S = any > = (
264+ primaryOption : P ,
265+ secondaryOptions : { [ key : string ] : S } ,
266+ context : PluginContext ,
267+ ) => ( root : Root , result : Result ) => void ;
268+
269+ interface StylelintRuleMeta {
270+ url : string ;
271+ deprecated ?: boolean ;
272+ fixable ?: boolean ;
273+ }
274+
275+ type StylelintRule < P = any , S = any > = StylelintRuleBase < P , S > & {
276+ ruleName : string ;
277+ meta ?: StylelintRuleMeta ;
278+ } ;
279+ // End: Extracted from stylelint
280+
261281export type PolarisMigrator = (
262282 primaryOption : true ,
263283 secondaryOptions : PluginOptions ,
264284 context : PluginContext ,
265285) => ( root : Root , result : Result ) => void ;
266286
267- export function createSassMigrator ( name : string , ruleFn : PolarisMigrator ) {
287+ // Expose a stylelint-like API for creating sass migrators so we can easily
288+ // migrate to that tool in the future.
289+ function convertStylelintRuleToPostcssProcessor ( ruleFn : StylelintRule ) {
268290 return ( fileInfo : FileInfo , _ : API , options : Options ) => {
269291 const plugin : Plugin = {
270- postcssPlugin : name ,
292+ postcssPlugin : ruleFn . ruleName ,
271293 // PostCSS will rewalk the AST every time a declaration/rule/etc is
272294 // mutated by a plugin. This can be useful in some cases, but in ours we
273295 // only want single-pass behaviour.
@@ -278,12 +300,14 @@ export function createSassMigrator(name: string, ruleFn: PolarisMigrator) {
278300 // subsequent passes.
279301 // 2) Using postcss's Once() plugin callback.
280302 //
281- // We're going with the Once() callback as it's idomatic PostCSS.
303+ // stylelint also uses `Once()`, so we're able to remove this once we've
304+ // migrated:
305+ // https://github.com/stylelint/stylelint/blob/cb425cb/lib/postcssPlugin.js#L22
282306 Once ( root , { result} ) {
283307 // NOTE: For fullest compatibility with stylelint, we initialise the
284- // rule here _inside_ the postcss Once function so multiple passes can
285- // be performed without rules accidentally retaining scoped variables,
286- // etc.
308+ // rule here _inside_ the postcss Once function just like stylelint
309+ // does. This means multiple passes can be performed without rules
310+ // accidentally retaining scoped variables, etc.
287311 ruleFn (
288312 // Normally, this comes from stylelint config, but for this shim we
289313 // just hard-code it, and instead rely on the "seconary" options
@@ -301,3 +325,16 @@ export function createSassMigrator(name: string, ruleFn: PolarisMigrator) {
301325 } ) . css ;
302326 } ;
303327}
328+
329+ export function createSassMigrator ( name : string , ruleFn : PolarisMigrator ) {
330+ const wrappedRule = ruleFn as StylelintRule ;
331+
332+ wrappedRule . ruleName = name ;
333+ wrappedRule . meta = {
334+ // TODO: link directly to the specific rule
335+ url : 'https://www.npmjs.com/package/@shopify/stylelint-polaris' ,
336+ fixable : true ,
337+ } ;
338+
339+ return convertStylelintRuleToPostcssProcessor ( wrappedRule ) ;
340+ }
0 commit comments