Skip to content

Commit bfa85dc

Browse files
committed
Better typing for polaris migrator functions
1 parent 4d70df3 commit bfa85dc

File tree

4 files changed

+84
-45
lines changed

4 files changed

+84
-45
lines changed

polaris-migrator/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,11 @@ Continuing the example, here is what the migration may look like if our goal is
287287
import {
288288
isSassFunction,
289289
createStylelintRule,
290+
StopWalkingFunctionNodes,
290291
} from '../../utilities/sass';
292+
import type {PolarisMigrator} from '../../utilities/sass';
291293

292-
function relaceSassFunction(_, {methods, options}, context) {
294+
const replaceHelloWorld: PolarisMigrator = (_, {methods}, context) => {
293295
return (root) => {
294296
methods.walkDecls(root, (decl, parsedValue) => {
295297
parsedValue.walk((node) => {
@@ -300,7 +302,8 @@ function relaceSassFunction(_, {methods, options}, context) {
300302
methods.report({
301303
node: decl,
302304
severity: 'error',
303-
message: 'Method hello() is no longer supported. Please migrate to world().'
305+
message:
306+
'Method hello() is no longer supported. Please migrate to world().',
304307
});
305308
}
306309

@@ -311,10 +314,7 @@ function relaceSassFunction(_, {methods, options}, context) {
311314
};
312315
};
313316

314-
export default createStylelintRule(
315-
'replace-sass-function',
316-
relaceSassFunction
317-
);
317+
export default createStylelintRule('replace-hello-world', replaceHelloWorld);
318318
```
319319

320320
A more complete example can be seen in [`replace-spacing-lengths.ts`](https://github.com/Shopify/polaris/blob/main/polaris-migrator/src/migrations/replace-spacing-lengths/replace-spacing-lengths.ts).

polaris-migrator/src/migrations/replace-spacing-lengths/replace-spacing-lengths.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default createStylelintRule(
3434
}
3535

3636
function handleSpaceProps() {
37-
parsedValue!.walk((node) => {
37+
parsedValue.walk((node) => {
3838
if (isNumericOperator(node)) {
3939
hasNumericOperator = true;
4040
return;

polaris-migrator/src/utilities/sass.ts

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ type StylelintRule<P = any, S = any> = StylelintRuleBase<P, S> & {
298298
meta?: StylelintRuleMeta;
299299
};
300300

301-
type PolarisStylelintRule<P = any, S = any> = (
301+
export type PolarisMigrator<P = any, S = any> = (
302302
primaryOption: P,
303303
secondaryOptions: {
304304
options: {[key: string]: S};
@@ -320,14 +320,14 @@ type PolarisStylelintRule<P = any, S = any> = (
320320
root: T,
321321
atRuleWalker: (
322322
atRule: AtRule,
323-
parsedValue?: ParsedValue,
323+
parsedValue: ParsedValue,
324324
) => false | void,
325325
) => void;
326326
walkDecls: <T extends Container>(
327327
root: T,
328328
declWalker: (
329329
decl: Declaration,
330-
parsedValue?: ParsedValue,
330+
parsedValue: ParsedValue,
331331
) => false | void,
332332
) => void;
333333
walkRules: <T extends Container>(
@@ -386,10 +386,7 @@ function convertStylelintRuleToPostcssProcessor(ruleFn: StylelintRule) {
386386
};
387387
}
388388

389-
export function createStylelintRule(
390-
ruleName: string,
391-
ruleFn: PolarisStylelintRule,
392-
) {
389+
export function createStylelintRule(ruleName: string, ruleFn: PolarisMigrator) {
393390
const wrappedRule: StylelintRule = ((
394391
primary,
395392
{
@@ -448,20 +445,49 @@ export function createStylelintRule(
448445
// stylelint.utils.report()
449446
const flushReportsToStylelint = flushReportsAsComments;
450447

451-
function createWalker<T extends PostCSSNode>({
452-
walker,
453-
valueParserKey,
454-
mutableKeys: incomingMutableKeys = [],
455-
serialiseSuggestion,
456-
}: {
457-
walker: (node: T, parsedValue?: ParsedValue) => false | void;
448+
function createWalker<T extends PostCSSNode>(args: {
449+
walker: (node: T) => false | void;
450+
mutableKeys?: (keyof T)[];
451+
serialiseSuggestion: (node: T) => string;
452+
}): (node: T) => false | void;
453+
function createWalker<T extends PostCSSNode>(args: {
454+
valueParserKey: keyof T;
455+
walker: (node: T, parsedValue: ParsedValue) => false | void;
456+
mutableKeys?: (keyof T)[];
457+
serialiseSuggestion: (node: T) => string;
458+
}): (node: T) => false | void;
459+
function createWalker<T extends PostCSSNode>(args: {
458460
valueParserKey?: keyof T;
461+
walker:
462+
| ((node: T) => false | void)
463+
| ((node: T, parsedValue: ParsedValue) => false | void);
459464
mutableKeys?: (keyof T)[];
460465
serialiseSuggestion: (node: T) => string;
461-
}) {
466+
}): (node: T) => false | void {
467+
// function createWalker<
468+
// T extends PostCSSNode,
469+
// S extends keyof T | undefined = undefined,
470+
// >(args: {
471+
// valueParserKey: S;
472+
// walker: S extends undefined
473+
// ? (node: T) => false | void
474+
// : (node: T, parsedValue: ParsedValue) => false | void;
475+
// mutableKeys?: (keyof T)[];
476+
// serialiseSuggestion: (node: T) => string;
477+
// }): (node: T) => false | void {
478+
const {
479+
valueParserKey,
480+
walker,
481+
mutableKeys: incomingMutableKeys = [],
482+
serialiseSuggestion,
483+
} = args;
484+
462485
const mutableKeys = [...incomingMutableKeys];
463486

464-
if (valueParserKey && !mutableKeys.includes(valueParserKey)) {
487+
if (
488+
typeof valueParserKey !== 'undefined' &&
489+
!mutableKeys.includes(valueParserKey)
490+
) {
465491
mutableKeys.push(valueParserKey);
466492
}
467493

@@ -471,19 +497,22 @@ export function createStylelintRule(
471497
return memo;
472498
}, {});
473499

474-
let parsedValue: ParsedValue | undefined;
475-
if (valueParserKey) {
476-
parsedValue = valueParser(node[valueParserKey] as unknown as string);
477-
}
478-
479-
const result = walker(node, parsedValue);
500+
let result: false | void;
501+
if (typeof valueParserKey !== 'undefined') {
502+
const parsedValue = valueParser(
503+
node[valueParserKey] as unknown as string,
504+
);
505+
result = walker(node, parsedValue);
480506

481-
if (context.fix) {
482-
if (valueParserKey && parsedValue) {
507+
if (context.fix && parsedValue) {
483508
(node[valueParserKey] as unknown as string) =
484509
parsedValue.toString();
485510
}
511+
} else {
512+
result = (walker as (node: T) => false | void)(node);
513+
}
486514

515+
if (context.fix) {
487516
const newValues = mutableKeys.reduce<Partial<T>>((memo, key) => {
488517
memo[key] = node[key];
489518
return memo;
@@ -525,7 +554,7 @@ export function createStylelintRule(
525554
walker: (node: PostCSSNode) => false | void,
526555
) {
527556
root.walkAtRules(
528-
createWalker<PostCSSNode>({
557+
createWalker({
529558
walker,
530559
serialiseSuggestion: (node) => node.toString(),
531560
}),
@@ -537,7 +566,7 @@ export function createStylelintRule(
537566
walker: (node: PostCSSNode) => false | void,
538567
) {
539568
root.walkAtRules(
540-
createWalker<PostCSSNode>({
569+
createWalker({
541570
walker,
542571
serialiseSuggestion: (node) => node.toString(),
543572
}),
@@ -546,10 +575,10 @@ export function createStylelintRule(
546575

547576
function walkAtRules<T extends Container>(
548577
root: T,
549-
walker: (node: AtRule, parsedValue?: ParsedValue) => false | void,
578+
walker: (node: AtRule, parsedValue: ParsedValue) => false | void,
550579
) {
551580
root.walkAtRules(
552-
createWalker<AtRule>({
581+
createWalker({
553582
walker,
554583
valueParserKey: 'params',
555584
mutableKeys: ['name', 'params'],
@@ -563,7 +592,7 @@ export function createStylelintRule(
563592
walker: (node: PostCSSComment) => false | void,
564593
) {
565594
root.walkComments(
566-
createWalker<PostCSSComment>({
595+
createWalker({
567596
walker,
568597
mutableKeys: ['text'],
569598
serialiseSuggestion: (node) => node.text,
@@ -573,10 +602,10 @@ export function createStylelintRule(
573602

574603
function walkDecls<T extends Container>(
575604
root: T,
576-
walker: (node: Declaration, parsedValue?: ParsedValue) => false | void,
605+
walker: (node: Declaration, parsedValue: ParsedValue) => false | void,
577606
) {
578607
root.walkDecls(
579-
createWalker<Declaration>({
608+
createWalker({
580609
walker,
581610
valueParserKey: 'value',
582611
mutableKeys: ['value', 'prop'],
@@ -590,7 +619,7 @@ export function createStylelintRule(
590619
walker: (node: PostCSSRule) => false | void,
591620
) {
592621
root.walkRules(
593-
createWalker<PostCSSRule>({
622+
createWalker({
594623
walker,
595624
mutableKeys: ['selector', 'selectors'],
596625
serialiseSuggestion: (node) => node.selector,

polaris-migrator/templates/sass-migration/{{kebabCase migrationName}}/{{kebabCase migrationName}}.ts.hbs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1-
import { isSassFunction, createStylelintRule } from '../../utilities/sass';
1+
import {
2+
isSassFunction,
3+
createStylelintRule,
4+
StopWalkingFunctionNodes,
5+
} from '../../utilities/sass';
6+
import type {PolarisMigrator} from '../../utilities/sass';
27

3-
// options will be passed in from cli / config.
4-
// Use context.fix to change behaviour based on if the user has passed the
5-
// `--fix` flag (always true for `polaris-migrator` CLI).
6-
function {{camelCase migrationName}}(_, {methods, options}, context) {
8+
const {{camelCase migrationName}}: PolarisMigrator = (
9+
_,
10+
// options will be passed in from cli / config.
11+
{methods /* , options */},
12+
// Use context.fix to change behaviour based on if the user has passed the
13+
// `--fix` flag (always true for `polaris-migrator` CLI).
14+
context,
15+
) => {
716
return (root) => {
817
methods.walkDecls(root, (decl, parsedValue) => {
918
// Using the parsedValue allows easy detection of individual functions and
@@ -20,7 +29,8 @@ function {{camelCase migrationName}}(_, {methods, options}, context) {
2029
methods.report({
2130
node: decl,
2231
severity: 'error',
23-
message: 'Method hello() is no longer supported. Please migrate to world().'
32+
message:
33+
'Method hello() is no longer supported. Please migrate to world().',
2434
});
2535
}
2636

0 commit comments

Comments
 (0)