@payloadcms/codemod 4.0.0-internal.44ac9c8 → 4.0.0-internal.4c2ee12
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 +3 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.help.d.ts +4 -0
- package/dist/cli.help.d.ts.map +1 -0
- package/dist/cli.help.js +29 -0
- package/dist/cli.help.js.map +1 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -1
- package/dist/cli.parseFlags.d.ts +1 -0
- package/dist/cli.parseFlags.d.ts.map +1 -1
- package/dist/cli.parseFlags.js +6 -0
- package/dist/cli.parseFlags.js.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +4 -0
- package/dist/registry.js.map +1 -1
- package/dist/runbook/payload-v4-upgrade.md +2 -2
- package/dist/runbook/v4.mdx +284 -10
- package/dist/transforms/migrate-admin-context-properties/basic.input.js +32 -0
- package/dist/transforms/migrate-admin-context-properties/basic.input.js.map +1 -0
- package/dist/transforms/migrate-admin-context-properties/basic.output.js +30 -0
- package/dist/transforms/migrate-admin-context-properties/basic.output.js.map +1 -0
- package/dist/transforms/migrate-admin-context-properties/index.d.ts +3 -0
- package/dist/transforms/migrate-admin-context-properties/index.d.ts.map +1 -0
- package/dist/transforms/migrate-admin-context-properties/index.js +302 -0
- package/dist/transforms/migrate-admin-context-properties/index.js.map +1 -0
- package/dist/transforms/migrate-admin-context-properties/no-match.input.js +30 -0
- package/dist/transforms/migrate-admin-context-properties/no-match.input.js.map +1 -0
- package/dist/transforms/migrate-admin-context-properties/no-match.output.js +30 -0
- package/dist/transforms/migrate-admin-context-properties/no-match.output.js.map +1 -0
- package/dist/transforms/migrate-field-component-types/index.d.ts.map +1 -1
- package/dist/transforms/migrate-field-component-types/index.js +4 -0
- package/dist/transforms/migrate-field-component-types/index.js.map +1 -1
- package/dist/transforms/migrate-sharp-to-transformer/basic.output.js +1 -1
- package/dist/transforms/migrate-sharp-to-transformer/basic.output.js.map +1 -1
- package/dist/transforms/migrate-sharp-to-transformer/existing-transformers.output.js +1 -1
- package/dist/transforms/migrate-sharp-to-transformer/existing-transformers.output.js.map +1 -1
- package/dist/transforms/migrate-sharp-to-transformer/index.d.ts.map +1 -1
- package/dist/transforms/migrate-sharp-to-transformer/index.js +232 -82
- package/dist/transforms/migrate-sharp-to-transformer/index.js.map +1 -1
- package/dist/transforms/remove-storage-always-insert-fields/index.d.ts.map +1 -1
- package/dist/transforms/remove-storage-always-insert-fields/index.js +4 -0
- package/dist/transforms/remove-storage-always-insert-fields/index.js.map +1 -1
- package/dist/transforms/rename-diff-value-props/basic.input.js +38 -0
- package/dist/transforms/rename-diff-value-props/basic.input.js.map +1 -0
- package/dist/transforms/rename-diff-value-props/basic.output.js +38 -0
- package/dist/transforms/rename-diff-value-props/basic.output.js.map +1 -0
- package/dist/transforms/rename-diff-value-props/index.d.ts +3 -0
- package/dist/transforms/rename-diff-value-props/index.d.ts.map +1 -0
- package/dist/transforms/rename-diff-value-props/index.js +328 -0
- package/dist/transforms/rename-diff-value-props/index.js.map +1 -0
- package/dist/transforms/rename-diff-value-props/no-match.input.js +8 -0
- package/dist/transforms/rename-diff-value-props/no-match.input.js.map +1 -0
- package/dist/transforms/rename-experimental-table-feature/index.d.ts.map +1 -1
- package/dist/transforms/rename-experimental-table-feature/index.js +7 -1
- package/dist/transforms/rename-experimental-table-feature/index.js.map +1 -1
- package/dist/upgrade/rewritePackageJson.d.ts.map +1 -1
- package/dist/upgrade/rewritePackageJson.js +52 -11
- package/dist/upgrade/rewritePackageJson.js.map +1 -1
- package/dist/utils/project.d.ts +7 -1
- package/dist/utils/project.d.ts.map +1 -1
- package/dist/utils/project.js +20 -7
- package/dist/utils/project.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const Destructured = ({ comparisonValue, field, versionValue })=>{
|
|
2
|
+
const hasChanged = comparisonValue !== versionValue;
|
|
3
|
+
return hasChanged ? `${String(comparisonValue)} -> ${String(versionValue)}` : field.name;
|
|
4
|
+
};
|
|
5
|
+
export const LegacyComponentType = ({ comparisonValue, versionValue = '' })=>`${String(comparisonValue)} -> ${String(versionValue)}`;
|
|
6
|
+
export const Aliased = ({ comparisonValue: before, versionValue: valueTo })=>[
|
|
7
|
+
before,
|
|
8
|
+
valueTo
|
|
9
|
+
];
|
|
10
|
+
export default async function PropsObject(props) {
|
|
11
|
+
const { comparisonValue, req } = props;
|
|
12
|
+
return [
|
|
13
|
+
comparisonValue,
|
|
14
|
+
props.versionValue,
|
|
15
|
+
props['comparisonValue'],
|
|
16
|
+
req.locale
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
export function LocalPropsType({ label, versionValue }) {
|
|
20
|
+
return [
|
|
21
|
+
label,
|
|
22
|
+
versionValue
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
export const RestProps = ({ field, ...rest })=>[
|
|
26
|
+
field,
|
|
27
|
+
rest.comparisonValue
|
|
28
|
+
];
|
|
29
|
+
export const NameCollision = ({ comparisonValue })=>{
|
|
30
|
+
const valueFrom = 'unrelated';
|
|
31
|
+
return [
|
|
32
|
+
comparisonValue,
|
|
33
|
+
valueFrom
|
|
34
|
+
];
|
|
35
|
+
};
|
|
36
|
+
export const formatValue = (value)=>String(value);
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=basic.input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/transforms/rename-diff-value-props/basic.input.ts"],"sourcesContent":["import type {\n FieldDiffServerProps,\n TextFieldDiffClientComponent,\n TextFieldDiffClientProps,\n TextFieldDiffServerProps,\n} from 'payload'\nimport type React from 'react'\n\nexport const Destructured: React.FC<TextFieldDiffClientProps> = ({\n comparisonValue,\n field,\n versionValue,\n}) => {\n const hasChanged = comparisonValue !== versionValue\n return hasChanged ? `${String(comparisonValue)} -> ${String(versionValue)}` : field.name\n}\n\nexport const LegacyComponentType: TextFieldDiffClientComponent = ({\n comparisonValue,\n versionValue = '',\n}) => `${String(comparisonValue)} -> ${String(versionValue)}`\n\nexport const Aliased = ({\n comparisonValue: before,\n versionValue: valueTo,\n}: TextFieldDiffClientProps) => [before, valueTo]\n\nexport default async function PropsObject(props: TextFieldDiffServerProps) {\n const { comparisonValue, req } = props\n return [comparisonValue, props.versionValue, props['comparisonValue'], req.locale]\n}\n\ntype PropsWithLabel = { label: string } & TextFieldDiffClientProps\n\nexport function LocalPropsType({ label, versionValue }: PropsWithLabel) {\n return [label, versionValue]\n}\n\nexport const RestProps = ({ field, ...rest }: FieldDiffServerProps) => [field, rest.comparisonValue]\n\nexport const NameCollision = ({ comparisonValue }: TextFieldDiffClientProps) => {\n const valueFrom = 'unrelated'\n return [comparisonValue, valueFrom]\n}\n\nexport const formatValue = (value: TextFieldDiffClientProps['versionValue']) => String(value)\n"],"names":["Destructured","comparisonValue","field","versionValue","hasChanged","String","name","LegacyComponentType","Aliased","before","valueTo","PropsObject","props","req","locale","LocalPropsType","label","RestProps","rest","NameCollision","valueFrom","formatValue","value"],"mappings":"AAQA,OAAO,MAAMA,eAAmD,CAAC,EAC/DC,eAAe,EACfC,KAAK,EACLC,YAAY,EACb;IACC,MAAMC,aAAaH,oBAAoBE;IACvC,OAAOC,aAAa,GAAGC,OAAOJ,iBAAiB,IAAI,EAAEI,OAAOF,eAAe,GAAGD,MAAMI,IAAI;AAC1F,EAAC;AAED,OAAO,MAAMC,sBAAoD,CAAC,EAChEN,eAAe,EACfE,eAAe,EAAE,EAClB,GAAK,GAAGE,OAAOJ,iBAAiB,IAAI,EAAEI,OAAOF,eAAe,CAAA;AAE7D,OAAO,MAAMK,UAAU,CAAC,EACtBP,iBAAiBQ,MAAM,EACvBN,cAAcO,OAAO,EACI,GAAK;QAACD;QAAQC;KAAQ,CAAA;AAEjD,eAAe,eAAeC,YAAYC,KAA+B;IACvE,MAAM,EAAEX,eAAe,EAAEY,GAAG,EAAE,GAAGD;IACjC,OAAO;QAACX;QAAiBW,MAAMT,YAAY;QAAES,KAAK,CAAC,kBAAkB;QAAEC,IAAIC,MAAM;KAAC;AACpF;AAIA,OAAO,SAASC,eAAe,EAAEC,KAAK,EAAEb,YAAY,EAAkB;IACpE,OAAO;QAACa;QAAOb;KAAa;AAC9B;AAEA,OAAO,MAAMc,YAAY,CAAC,EAAEf,KAAK,EAAE,GAAGgB,MAA4B,GAAK;QAAChB;QAAOgB,KAAKjB,eAAe;KAAC,CAAA;AAEpG,OAAO,MAAMkB,gBAAgB,CAAC,EAAElB,eAAe,EAA4B;IACzE,MAAMmB,YAAY;IAClB,OAAO;QAACnB;QAAiBmB;KAAU;AACrC,EAAC;AAED,OAAO,MAAMC,cAAc,CAACC,QAAoDjB,OAAOiB,OAAM"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const Destructured = ({ valueFrom, field, valueTo })=>{
|
|
2
|
+
const hasChanged = valueFrom !== valueTo;
|
|
3
|
+
return hasChanged ? `${String(valueFrom)} -> ${String(valueTo)}` : field.name;
|
|
4
|
+
};
|
|
5
|
+
export const LegacyComponentType = ({ valueFrom, valueTo = '' })=>`${String(valueFrom)} -> ${String(valueTo)}`;
|
|
6
|
+
export const Aliased = ({ valueFrom: before, valueTo })=>[
|
|
7
|
+
before,
|
|
8
|
+
valueTo
|
|
9
|
+
];
|
|
10
|
+
export default async function PropsObject(props) {
|
|
11
|
+
const { valueFrom, req } = props;
|
|
12
|
+
return [
|
|
13
|
+
valueFrom,
|
|
14
|
+
props.valueTo,
|
|
15
|
+
props['valueFrom'],
|
|
16
|
+
req.locale
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
export function LocalPropsType({ label, valueTo }) {
|
|
20
|
+
return [
|
|
21
|
+
label,
|
|
22
|
+
valueTo
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
export const RestProps = ({ field, ...rest })=>[
|
|
26
|
+
field,
|
|
27
|
+
rest.valueFrom
|
|
28
|
+
];
|
|
29
|
+
export const NameCollision = ({ valueFrom: comparisonValue })=>{
|
|
30
|
+
const valueFrom = 'unrelated';
|
|
31
|
+
return [
|
|
32
|
+
comparisonValue,
|
|
33
|
+
valueFrom
|
|
34
|
+
];
|
|
35
|
+
};
|
|
36
|
+
export const formatValue = (value)=>String(value);
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=basic.output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/transforms/rename-diff-value-props/basic.output.ts"],"sourcesContent":["import type {\n FieldDiffServerProps,\n TextFieldDiffClientComponent,\n TextFieldDiffClientProps,\n TextFieldDiffServerProps,\n} from 'payload'\nimport type React from 'react'\n\nexport const Destructured: React.FC<TextFieldDiffClientProps> = ({\n valueFrom,\n field,\n valueTo,\n}) => {\n const hasChanged = valueFrom !== valueTo\n return hasChanged ? `${String(valueFrom)} -> ${String(valueTo)}` : field.name\n}\n\nexport const LegacyComponentType: TextFieldDiffClientComponent = ({\n valueFrom,\n valueTo = '',\n}) => `${String(valueFrom)} -> ${String(valueTo)}`\n\nexport const Aliased = ({\n valueFrom: before,\n valueTo,\n}: TextFieldDiffClientProps) => [before, valueTo]\n\nexport default async function PropsObject(props: TextFieldDiffServerProps) {\n const { valueFrom, req } = props\n return [valueFrom, props.valueTo, props['valueFrom'], req.locale]\n}\n\ntype PropsWithLabel = { label: string } & TextFieldDiffClientProps\n\nexport function LocalPropsType({ label, valueTo }: PropsWithLabel) {\n return [label, valueTo]\n}\n\nexport const RestProps = ({ field, ...rest }: FieldDiffServerProps) => [field, rest.valueFrom]\n\nexport const NameCollision = ({ valueFrom: comparisonValue }: TextFieldDiffClientProps) => {\n const valueFrom = 'unrelated'\n return [comparisonValue, valueFrom]\n}\n\nexport const formatValue = (value: TextFieldDiffClientProps['valueTo']) => String(value)\n"],"names":["Destructured","valueFrom","field","valueTo","hasChanged","String","name","LegacyComponentType","Aliased","before","PropsObject","props","req","locale","LocalPropsType","label","RestProps","rest","NameCollision","comparisonValue","formatValue","value"],"mappings":"AAQA,OAAO,MAAMA,eAAmD,CAAC,EAC/DC,SAAS,EACTC,KAAK,EACLC,OAAO,EACR;IACC,MAAMC,aAAaH,cAAcE;IACjC,OAAOC,aAAa,GAAGC,OAAOJ,WAAW,IAAI,EAAEI,OAAOF,UAAU,GAAGD,MAAMI,IAAI;AAC/E,EAAC;AAED,OAAO,MAAMC,sBAAoD,CAAC,EAChEN,SAAS,EACTE,UAAU,EAAE,EACb,GAAK,GAAGE,OAAOJ,WAAW,IAAI,EAAEI,OAAOF,UAAU,CAAA;AAElD,OAAO,MAAMK,UAAU,CAAC,EACtBP,WAAWQ,MAAM,EACjBN,OAAO,EACkB,GAAK;QAACM;QAAQN;KAAQ,CAAA;AAEjD,eAAe,eAAeO,YAAYC,KAA+B;IACvE,MAAM,EAAEV,SAAS,EAAEW,GAAG,EAAE,GAAGD;IAC3B,OAAO;QAACV;QAAWU,MAAMR,OAAO;QAAEQ,KAAK,CAAC,YAAY;QAAEC,IAAIC,MAAM;KAAC;AACnE;AAIA,OAAO,SAASC,eAAe,EAAEC,KAAK,EAAEZ,OAAO,EAAkB;IAC/D,OAAO;QAACY;QAAOZ;KAAQ;AACzB;AAEA,OAAO,MAAMa,YAAY,CAAC,EAAEd,KAAK,EAAE,GAAGe,MAA4B,GAAK;QAACf;QAAOe,KAAKhB,SAAS;KAAC,CAAA;AAE9F,OAAO,MAAMiB,gBAAgB,CAAC,EAAEjB,WAAWkB,eAAe,EAA4B;IACpF,MAAMlB,YAAY;IAClB,OAAO;QAACkB;QAAiBlB;KAAU;AACrC,EAAC;AAED,OAAO,MAAMmB,cAAc,CAACC,QAA+ChB,OAAOgB,OAAM"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transforms/rename-diff-value-props/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAsB/C,eAAO,MAAM,oBAAoB,EAAE,SAwClC,CAAA"}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { Node, SyntaxKind } from 'ts-morph';
|
|
2
|
+
const RENAMED_PROPS = new Map([
|
|
3
|
+
[
|
|
4
|
+
'comparisonValue',
|
|
5
|
+
'valueFrom'
|
|
6
|
+
],
|
|
7
|
+
[
|
|
8
|
+
'versionValue',
|
|
9
|
+
'valueTo'
|
|
10
|
+
]
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* Matches every Diff component type exported from `payload`, in both the v3 component-alias
|
|
14
|
+
* form (`TextFieldDiffClientComponent`) and the props form (`TextFieldDiffClientProps`), so this
|
|
15
|
+
* transform works regardless of whether `migrate-field-component-types` has already run.
|
|
16
|
+
*/ const DIFF_TYPE_NAME_PATTERN = /^[A-Za-z]*FieldDiff(?:Client|Server)(?:Component|Props)$/;
|
|
17
|
+
/**
|
|
18
|
+
* Every rewrite removes one old prop name, so the per-file loop always terminates. This cap only
|
|
19
|
+
* guards against an unexpected regression turning it into an infinite loop.
|
|
20
|
+
*/ const MAX_REWRITES_PER_FILE = 1000;
|
|
21
|
+
export const renameDiffValueProps = {
|
|
22
|
+
name: 'rename-diff-value-props',
|
|
23
|
+
apply: ({ project })=>{
|
|
24
|
+
const filesChanged = [];
|
|
25
|
+
const notes = [];
|
|
26
|
+
for (const sourceFile of project.getSourceFiles()){
|
|
27
|
+
if (sourceFile.isDeclarationFile() || sourceFile.isInNodeModules()) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const diffTypeNames = collectDiffTypeNames({
|
|
31
|
+
sourceFile
|
|
32
|
+
});
|
|
33
|
+
if (diffTypeNames.size === 0) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
let rewriteCount = 0;
|
|
37
|
+
while(rewriteCount < MAX_REWRITES_PER_FILE && rewriteNextOccurrence({
|
|
38
|
+
diffTypeNames,
|
|
39
|
+
sourceFile
|
|
40
|
+
})){
|
|
41
|
+
rewriteCount++;
|
|
42
|
+
}
|
|
43
|
+
if (rewriteCount > 0) {
|
|
44
|
+
filesChanged.push(sourceFile.getFilePath());
|
|
45
|
+
}
|
|
46
|
+
notes.push(...collectLeftoverNotes({
|
|
47
|
+
sourceFile
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
filesChanged,
|
|
52
|
+
...notes.length > 0 ? {
|
|
53
|
+
notes
|
|
54
|
+
} : {}
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
description: 'Rename the `comparisonValue` and `versionValue` props read by custom Diff components to `valueFrom` and `valueTo`.'
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Returns the local names of Diff component types imported from `payload`, plus same-file type
|
|
61
|
+
* aliases and interfaces built from them (e.g. `type Props = TextFieldDiffClientProps & { ... }`).
|
|
62
|
+
*/ function collectDiffTypeNames({ sourceFile }) {
|
|
63
|
+
const diffTypeNames = new Set();
|
|
64
|
+
for (const importDeclaration of sourceFile.getImportDeclarations()){
|
|
65
|
+
if (importDeclaration.getModuleSpecifierValue() !== 'payload') {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
for (const namedImport of importDeclaration.getNamedImports()){
|
|
69
|
+
if (DIFF_TYPE_NAME_PATTERN.test(namedImport.getName())) {
|
|
70
|
+
diffTypeNames.add(namedImport.getAliasNode()?.getText() ?? namedImport.getName());
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (diffTypeNames.size === 0) {
|
|
75
|
+
return diffTypeNames;
|
|
76
|
+
}
|
|
77
|
+
let hasFoundNewName = true;
|
|
78
|
+
while(hasFoundNewName){
|
|
79
|
+
hasFoundNewName = false;
|
|
80
|
+
const derivedTypeNames = [
|
|
81
|
+
...sourceFile.getTypeAliases().filter((typeAlias)=>referencesDiffType({
|
|
82
|
+
diffTypeNames,
|
|
83
|
+
typeNode: typeAlias.getTypeNodeOrThrow()
|
|
84
|
+
})),
|
|
85
|
+
...sourceFile.getInterfaces().filter((declaration)=>declaration.getExtends().some((heritage)=>diffTypeNames.has(heritage.getExpression().getText())))
|
|
86
|
+
].map((declaration)=>declaration.getName());
|
|
87
|
+
for (const typeName of derivedTypeNames){
|
|
88
|
+
if (!diffTypeNames.has(typeName)) {
|
|
89
|
+
diffTypeNames.add(typeName);
|
|
90
|
+
hasFoundNewName = true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return diffTypeNames;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Applies a single rewrite and reports whether one was made. Renames replace source text, which
|
|
98
|
+
* invalidates previously queried nodes, so the caller re-scans the file after every rewrite.
|
|
99
|
+
*/ function rewriteNextOccurrence({ diffTypeNames, sourceFile }) {
|
|
100
|
+
for (const component of findDiffComponents({
|
|
101
|
+
diffTypeNames,
|
|
102
|
+
sourceFile
|
|
103
|
+
})){
|
|
104
|
+
const propsParameterName = component.getParameters()[0].getNameNode();
|
|
105
|
+
const propsBindingPatterns = [];
|
|
106
|
+
const propsIdentifiers = [];
|
|
107
|
+
if (Node.isObjectBindingPattern(propsParameterName)) {
|
|
108
|
+
propsBindingPatterns.push(propsParameterName);
|
|
109
|
+
const restElementName = propsParameterName.getElements().find((element)=>element.getDotDotDotToken())?.getNameNode();
|
|
110
|
+
if (restElementName && Node.isIdentifier(restElementName)) {
|
|
111
|
+
propsIdentifiers.push(restElementName);
|
|
112
|
+
}
|
|
113
|
+
} else if (Node.isIdentifier(propsParameterName)) {
|
|
114
|
+
propsIdentifiers.push(propsParameterName);
|
|
115
|
+
}
|
|
116
|
+
const readsProps = (node)=>Node.isIdentifier(node) && propsIdentifiers.some((propsIdentifier)=>isReferenceTo({
|
|
117
|
+
declaration: propsIdentifier,
|
|
118
|
+
identifier: node
|
|
119
|
+
}));
|
|
120
|
+
for (const declaration of component.getDescendantsOfKind(SyntaxKind.VariableDeclaration)){
|
|
121
|
+
const declarationName = declaration.getNameNode();
|
|
122
|
+
const initializer = declaration.getInitializer();
|
|
123
|
+
if (Node.isObjectBindingPattern(declarationName) && initializer && readsProps(initializer)) {
|
|
124
|
+
propsBindingPatterns.push(declarationName);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
for (const pattern of propsBindingPatterns){
|
|
128
|
+
for (const element of pattern.getElements()){
|
|
129
|
+
if (rewriteBindingElement({
|
|
130
|
+
component,
|
|
131
|
+
element
|
|
132
|
+
})) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
for (const access of component.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression)){
|
|
138
|
+
const newName = RENAMED_PROPS.get(access.getName());
|
|
139
|
+
if (newName && readsProps(access.getExpression())) {
|
|
140
|
+
access.getNameNode().replaceWithText(newName);
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
for (const access of component.getDescendantsOfKind(SyntaxKind.ElementAccessExpression)){
|
|
145
|
+
const argument = access.getArgumentExpression();
|
|
146
|
+
if (!argument || !Node.isStringLiteral(argument) || !readsProps(access.getExpression())) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const newName = RENAMED_PROPS.get(argument.getLiteralValue());
|
|
150
|
+
if (newName) {
|
|
151
|
+
argument.setLiteralValue(newName);
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
for (const indexedAccess of sourceFile.getDescendantsOfKind(SyntaxKind.IndexedAccessType)){
|
|
157
|
+
const indexType = indexedAccess.getIndexTypeNode();
|
|
158
|
+
const literal = Node.isLiteralTypeNode(indexType) ? indexType.getLiteral() : undefined;
|
|
159
|
+
if (!literal || !Node.isStringLiteral(literal) || !referencesDiffType({
|
|
160
|
+
diffTypeNames,
|
|
161
|
+
typeNode: indexedAccess.getObjectTypeNode()
|
|
162
|
+
})) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const newName = RENAMED_PROPS.get(literal.getLiteralValue());
|
|
166
|
+
if (newName) {
|
|
167
|
+
literal.setLiteralValue(newName);
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Finds functions whose first parameter is typed with a Diff type, either directly
|
|
175
|
+
* (`(props: TextFieldDiffClientProps) => ...`) or through the variable they are assigned to
|
|
176
|
+
* (`const Diff: React.FC<TextFieldDiffClientProps> = (props) => ...`).
|
|
177
|
+
*/ function findDiffComponents({ diffTypeNames, sourceFile }) {
|
|
178
|
+
const functions = [
|
|
179
|
+
...sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction),
|
|
180
|
+
...sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration),
|
|
181
|
+
...sourceFile.getDescendantsOfKind(SyntaxKind.FunctionExpression)
|
|
182
|
+
];
|
|
183
|
+
return functions.filter((component)=>{
|
|
184
|
+
const propsParameter = component.getParameters()[0];
|
|
185
|
+
if (!propsParameter) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
const parent = component.getParent();
|
|
189
|
+
const typeNodes = [
|
|
190
|
+
propsParameter.getTypeNode(),
|
|
191
|
+
Node.isVariableDeclaration(parent) ? parent.getTypeNode() : undefined
|
|
192
|
+
];
|
|
193
|
+
return typeNodes.some((typeNode)=>typeNode && referencesDiffType({
|
|
194
|
+
diffTypeNames,
|
|
195
|
+
typeNode
|
|
196
|
+
}));
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
function referencesDiffType({ diffTypeNames, typeNode }) {
|
|
200
|
+
return [
|
|
201
|
+
typeNode,
|
|
202
|
+
...typeNode.getDescendantsOfKind(SyntaxKind.TypeReference)
|
|
203
|
+
].some((node)=>Node.isTypeReference(node) && diffTypeNames.has(node.getTypeName().getText()) && !isWrappedWithin({
|
|
204
|
+
node,
|
|
205
|
+
root: typeNode
|
|
206
|
+
}));
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Whether `node` sits inside a type that wraps the props rather than describing them, such as
|
|
210
|
+
* `{ diff: TextFieldDiffClientProps }` or `TextFieldDiffClientProps['valueFrom']`.
|
|
211
|
+
*/ function isWrappedWithin({ node, root }) {
|
|
212
|
+
const stopAt = root.getParent();
|
|
213
|
+
for(let ancestor = node.getParent(); ancestor && ancestor !== stopAt; ancestor = ancestor.getParent()){
|
|
214
|
+
if (Node.isPropertySignature(ancestor) || Node.isIndexedAccessTypeNode(ancestor)) {
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Renames the destructured key of a single binding element. Returns `false` when the element
|
|
222
|
+
* doesn't destructure one of the renamed props.
|
|
223
|
+
*/ function rewriteBindingElement({ component, element }) {
|
|
224
|
+
if (element.getDotDotDotToken()) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
const nameNode = element.getNameNode();
|
|
228
|
+
const propertyNameNode = element.getPropertyNameNode();
|
|
229
|
+
const propertyName = propertyNameNode ? getPropertyNameText({
|
|
230
|
+
node: propertyNameNode
|
|
231
|
+
}) : nameNode.getText();
|
|
232
|
+
const newName = propertyName ? RENAMED_PROPS.get(propertyName) : undefined;
|
|
233
|
+
if (!propertyName || !newName) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
const initializer = element.getInitializer();
|
|
237
|
+
const initializerText = initializer ? ` = ${initializer.getText()}` : '';
|
|
238
|
+
if (propertyNameNode) {
|
|
239
|
+
const localName = nameNode.getText();
|
|
240
|
+
element.replaceWithText(localName === newName ? `${newName}${initializerText}` : `${newName}: ${localName}${initializerText}`);
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
// A shorthand `{ comparisonValue }` also declares a local variable. Renaming it through the
|
|
244
|
+
// language service updates every reference, and `usePrefixAndSuffixText` leaves the element as
|
|
245
|
+
// `comparisonValue: valueFrom`, which the next pass collapses to `valueFrom`.
|
|
246
|
+
if (Node.isIdentifier(nameNode) && !containsIdentifierNamed({
|
|
247
|
+
name: newName,
|
|
248
|
+
node: component
|
|
249
|
+
})) {
|
|
250
|
+
const sourceFile = element.getSourceFile();
|
|
251
|
+
const textBeforeRename = sourceFile.getFullText();
|
|
252
|
+
try {
|
|
253
|
+
nameNode.rename(newName, {
|
|
254
|
+
usePrefixAndSuffixText: true
|
|
255
|
+
});
|
|
256
|
+
} catch {
|
|
257
|
+
// Fall back to keeping the local variable name below
|
|
258
|
+
}
|
|
259
|
+
if (sourceFile.getFullText() !== textBeforeRename) {
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
element.replaceWithText(`${newName}: ${propertyName}${initializerText}`);
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
function getPropertyNameText({ node }) {
|
|
267
|
+
if (Node.isIdentifier(node)) {
|
|
268
|
+
return node.getText();
|
|
269
|
+
}
|
|
270
|
+
if (Node.isStringLiteral(node)) {
|
|
271
|
+
return node.getLiteralValue();
|
|
272
|
+
}
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
function containsIdentifierNamed({ name, node }) {
|
|
276
|
+
return node.getDescendantsOfKind(SyntaxKind.Identifier).some((identifier)=>identifier.getText() === name);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Compares symbols so an inner variable that shadows the props parameter isn't mistaken for it.
|
|
280
|
+
* Falls back to comparing names when the type checker can't resolve a symbol.
|
|
281
|
+
*/ function isReferenceTo({ declaration, identifier }) {
|
|
282
|
+
if (identifier.getText() !== declaration.getText()) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
const declarationSymbol = declaration.getSymbol();
|
|
286
|
+
return !declarationSymbol || identifier.getSymbol() === declarationSymbol;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Flags old prop names that remain in a property position, e.g. a JSX attribute passing
|
|
290
|
+
* `comparisonValue` to another component, or `Pick<Props, 'versionValue'>`. Local variables that
|
|
291
|
+
* merely share the old name are left alone.
|
|
292
|
+
*/ function collectLeftoverNotes({ sourceFile }) {
|
|
293
|
+
const notedLocations = new Set();
|
|
294
|
+
const notes = [];
|
|
295
|
+
const candidates = [
|
|
296
|
+
...sourceFile.getDescendantsOfKind(SyntaxKind.Identifier).filter((identifier)=>isPropertyNamePosition({
|
|
297
|
+
identifier
|
|
298
|
+
})),
|
|
299
|
+
...sourceFile.getDescendantsOfKind(SyntaxKind.StringLiteral)
|
|
300
|
+
].sort((a, b)=>a.getStart() - b.getStart());
|
|
301
|
+
for (const candidate of candidates){
|
|
302
|
+
const oldName = Node.isStringLiteral(candidate) ? candidate.getLiteralValue() : candidate.getText();
|
|
303
|
+
const newName = RENAMED_PROPS.get(oldName);
|
|
304
|
+
const location = `${sourceFile.getFilePath()}:${candidate.getStartLineNumber()}`;
|
|
305
|
+
if (!newName || notedLocations.has(`${location}:${oldName}`)) {
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
notedLocations.add(`${location}:${oldName}`);
|
|
309
|
+
notes.push(`${location}: \`${oldName}\` was not migrated. If it refers to a Diff component prop, rename it to \`${newName}\`.`);
|
|
310
|
+
}
|
|
311
|
+
return notes;
|
|
312
|
+
}
|
|
313
|
+
function isPropertyNamePosition({ identifier }) {
|
|
314
|
+
const parent = identifier.getParent();
|
|
315
|
+
if (Node.isShorthandPropertyAssignment(parent) || Node.isJsxAttribute(parent)) {
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
if (Node.isBindingElement(parent)) {
|
|
319
|
+
const propertyNameNode = parent.getPropertyNameNode();
|
|
320
|
+
return propertyNameNode ? propertyNameNode === identifier : !parent.getDotDotDotToken();
|
|
321
|
+
}
|
|
322
|
+
if (Node.isPropertyAccessExpression(parent) || Node.isPropertyAssignment(parent) || Node.isPropertySignature(parent)) {
|
|
323
|
+
return parent.getNameNode() === identifier;
|
|
324
|
+
}
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/transforms/rename-diff-value-props/index.ts"],"sourcesContent":["import type {\n ArrowFunction,\n BindingElement,\n FunctionDeclaration,\n FunctionExpression,\n Identifier,\n ObjectBindingPattern,\n SourceFile,\n TypeNode,\n} from 'ts-morph'\n\nimport { Node, SyntaxKind } from 'ts-morph'\n\nimport type { Transform } from '../../types.js'\n\nconst RENAMED_PROPS = new Map([\n ['comparisonValue', 'valueFrom'],\n ['versionValue', 'valueTo'],\n])\n\n/**\n * Matches every Diff component type exported from `payload`, in both the v3 component-alias\n * form (`TextFieldDiffClientComponent`) and the props form (`TextFieldDiffClientProps`), so this\n * transform works regardless of whether `migrate-field-component-types` has already run.\n */\nconst DIFF_TYPE_NAME_PATTERN = /^[A-Za-z]*FieldDiff(?:Client|Server)(?:Component|Props)$/\n\n/**\n * Every rewrite removes one old prop name, so the per-file loop always terminates. This cap only\n * guards against an unexpected regression turning it into an infinite loop.\n */\nconst MAX_REWRITES_PER_FILE = 1000\n\ntype ComponentFunction = ArrowFunction | FunctionDeclaration | FunctionExpression\n\nexport const renameDiffValueProps: Transform = {\n name: 'rename-diff-value-props',\n apply: ({ project }) => {\n const filesChanged: string[] = []\n const notes: string[] = []\n\n for (const sourceFile of project.getSourceFiles()) {\n if (sourceFile.isDeclarationFile() || sourceFile.isInNodeModules()) {\n continue\n }\n\n const diffTypeNames = collectDiffTypeNames({ sourceFile })\n\n if (diffTypeNames.size === 0) {\n continue\n }\n\n let rewriteCount = 0\n\n while (\n rewriteCount < MAX_REWRITES_PER_FILE &&\n rewriteNextOccurrence({ diffTypeNames, sourceFile })\n ) {\n rewriteCount++\n }\n\n if (rewriteCount > 0) {\n filesChanged.push(sourceFile.getFilePath())\n }\n\n notes.push(...collectLeftoverNotes({ sourceFile }))\n }\n\n return {\n filesChanged,\n ...(notes.length > 0 ? { notes } : {}),\n }\n },\n description:\n 'Rename the `comparisonValue` and `versionValue` props read by custom Diff components to `valueFrom` and `valueTo`.',\n}\n\n/**\n * Returns the local names of Diff component types imported from `payload`, plus same-file type\n * aliases and interfaces built from them (e.g. `type Props = TextFieldDiffClientProps & { ... }`).\n */\nfunction collectDiffTypeNames({ sourceFile }: { sourceFile: SourceFile }): Set<string> {\n const diffTypeNames = new Set<string>()\n\n for (const importDeclaration of sourceFile.getImportDeclarations()) {\n if (importDeclaration.getModuleSpecifierValue() !== 'payload') {\n continue\n }\n\n for (const namedImport of importDeclaration.getNamedImports()) {\n if (DIFF_TYPE_NAME_PATTERN.test(namedImport.getName())) {\n diffTypeNames.add(namedImport.getAliasNode()?.getText() ?? namedImport.getName())\n }\n }\n }\n\n if (diffTypeNames.size === 0) {\n return diffTypeNames\n }\n\n let hasFoundNewName = true\n\n while (hasFoundNewName) {\n hasFoundNewName = false\n\n const derivedTypeNames = [\n ...sourceFile\n .getTypeAliases()\n .filter((typeAlias) =>\n referencesDiffType({ diffTypeNames, typeNode: typeAlias.getTypeNodeOrThrow() }),\n ),\n ...sourceFile\n .getInterfaces()\n .filter((declaration) =>\n declaration\n .getExtends()\n .some((heritage) => diffTypeNames.has(heritage.getExpression().getText())),\n ),\n ].map((declaration) => declaration.getName())\n\n for (const typeName of derivedTypeNames) {\n if (!diffTypeNames.has(typeName)) {\n diffTypeNames.add(typeName)\n hasFoundNewName = true\n }\n }\n }\n\n return diffTypeNames\n}\n\n/**\n * Applies a single rewrite and reports whether one was made. Renames replace source text, which\n * invalidates previously queried nodes, so the caller re-scans the file after every rewrite.\n */\nfunction rewriteNextOccurrence({\n diffTypeNames,\n sourceFile,\n}: {\n diffTypeNames: Set<string>\n sourceFile: SourceFile\n}): boolean {\n for (const component of findDiffComponents({ diffTypeNames, sourceFile })) {\n const propsParameterName = component.getParameters()[0]!.getNameNode()\n const propsBindingPatterns: ObjectBindingPattern[] = []\n const propsIdentifiers: Identifier[] = []\n\n if (Node.isObjectBindingPattern(propsParameterName)) {\n propsBindingPatterns.push(propsParameterName)\n\n const restElementName = propsParameterName\n .getElements()\n .find((element) => element.getDotDotDotToken())\n ?.getNameNode()\n\n if (restElementName && Node.isIdentifier(restElementName)) {\n propsIdentifiers.push(restElementName)\n }\n } else if (Node.isIdentifier(propsParameterName)) {\n propsIdentifiers.push(propsParameterName)\n }\n\n const readsProps = (node: Node): boolean =>\n Node.isIdentifier(node) &&\n propsIdentifiers.some((propsIdentifier) =>\n isReferenceTo({ declaration: propsIdentifier, identifier: node }),\n )\n\n for (const declaration of component.getDescendantsOfKind(SyntaxKind.VariableDeclaration)) {\n const declarationName = declaration.getNameNode()\n const initializer = declaration.getInitializer()\n\n if (Node.isObjectBindingPattern(declarationName) && initializer && readsProps(initializer)) {\n propsBindingPatterns.push(declarationName)\n }\n }\n\n for (const pattern of propsBindingPatterns) {\n for (const element of pattern.getElements()) {\n if (rewriteBindingElement({ component, element })) {\n return true\n }\n }\n }\n\n for (const access of component.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression)) {\n const newName = RENAMED_PROPS.get(access.getName())\n\n if (newName && readsProps(access.getExpression())) {\n access.getNameNode().replaceWithText(newName)\n return true\n }\n }\n\n for (const access of component.getDescendantsOfKind(SyntaxKind.ElementAccessExpression)) {\n const argument = access.getArgumentExpression()\n\n if (!argument || !Node.isStringLiteral(argument) || !readsProps(access.getExpression())) {\n continue\n }\n\n const newName = RENAMED_PROPS.get(argument.getLiteralValue())\n\n if (newName) {\n argument.setLiteralValue(newName)\n return true\n }\n }\n }\n\n for (const indexedAccess of sourceFile.getDescendantsOfKind(SyntaxKind.IndexedAccessType)) {\n const indexType = indexedAccess.getIndexTypeNode()\n const literal = Node.isLiteralTypeNode(indexType) ? indexType.getLiteral() : undefined\n\n if (\n !literal ||\n !Node.isStringLiteral(literal) ||\n !referencesDiffType({ diffTypeNames, typeNode: indexedAccess.getObjectTypeNode() })\n ) {\n continue\n }\n\n const newName = RENAMED_PROPS.get(literal.getLiteralValue())\n\n if (newName) {\n literal.setLiteralValue(newName)\n return true\n }\n }\n\n return false\n}\n\n/**\n * Finds functions whose first parameter is typed with a Diff type, either directly\n * (`(props: TextFieldDiffClientProps) => ...`) or through the variable they are assigned to\n * (`const Diff: React.FC<TextFieldDiffClientProps> = (props) => ...`).\n */\nfunction findDiffComponents({\n diffTypeNames,\n sourceFile,\n}: {\n diffTypeNames: Set<string>\n sourceFile: SourceFile\n}): ComponentFunction[] {\n const functions: ComponentFunction[] = [\n ...sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction),\n ...sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration),\n ...sourceFile.getDescendantsOfKind(SyntaxKind.FunctionExpression),\n ]\n\n return functions.filter((component) => {\n const propsParameter = component.getParameters()[0]\n\n if (!propsParameter) {\n return false\n }\n\n const parent = component.getParent()\n const typeNodes = [\n propsParameter.getTypeNode(),\n Node.isVariableDeclaration(parent) ? parent.getTypeNode() : undefined,\n ]\n\n return typeNodes.some((typeNode) => typeNode && referencesDiffType({ diffTypeNames, typeNode }))\n })\n}\n\nfunction referencesDiffType({\n diffTypeNames,\n typeNode,\n}: {\n diffTypeNames: Set<string>\n typeNode: TypeNode\n}): boolean {\n return [typeNode, ...typeNode.getDescendantsOfKind(SyntaxKind.TypeReference)].some(\n (node) =>\n Node.isTypeReference(node) &&\n diffTypeNames.has(node.getTypeName().getText()) &&\n !isWrappedWithin({ node, root: typeNode }),\n )\n}\n\n/**\n * Whether `node` sits inside a type that wraps the props rather than describing them, such as\n * `{ diff: TextFieldDiffClientProps }` or `TextFieldDiffClientProps['valueFrom']`.\n */\nfunction isWrappedWithin({ node, root }: { node: Node; root: TypeNode }): boolean {\n const stopAt = root.getParent()\n\n for (\n let ancestor = node.getParent();\n ancestor && ancestor !== stopAt;\n ancestor = ancestor.getParent()\n ) {\n if (Node.isPropertySignature(ancestor) || Node.isIndexedAccessTypeNode(ancestor)) {\n return true\n }\n }\n\n return false\n}\n\n/**\n * Renames the destructured key of a single binding element. Returns `false` when the element\n * doesn't destructure one of the renamed props.\n */\nfunction rewriteBindingElement({\n component,\n element,\n}: {\n component: ComponentFunction\n element: BindingElement\n}): boolean {\n if (element.getDotDotDotToken()) {\n return false\n }\n\n const nameNode = element.getNameNode()\n const propertyNameNode = element.getPropertyNameNode()\n const propertyName = propertyNameNode\n ? getPropertyNameText({ node: propertyNameNode })\n : nameNode.getText()\n const newName = propertyName ? RENAMED_PROPS.get(propertyName) : undefined\n\n if (!propertyName || !newName) {\n return false\n }\n\n const initializer = element.getInitializer()\n const initializerText = initializer ? ` = ${initializer.getText()}` : ''\n\n if (propertyNameNode) {\n const localName = nameNode.getText()\n\n element.replaceWithText(\n localName === newName\n ? `${newName}${initializerText}`\n : `${newName}: ${localName}${initializerText}`,\n )\n return true\n }\n\n // A shorthand `{ comparisonValue }` also declares a local variable. Renaming it through the\n // language service updates every reference, and `usePrefixAndSuffixText` leaves the element as\n // `comparisonValue: valueFrom`, which the next pass collapses to `valueFrom`.\n if (Node.isIdentifier(nameNode) && !containsIdentifierNamed({ name: newName, node: component })) {\n const sourceFile = element.getSourceFile()\n const textBeforeRename = sourceFile.getFullText()\n\n try {\n nameNode.rename(newName, { usePrefixAndSuffixText: true })\n } catch {\n // Fall back to keeping the local variable name below\n }\n\n if (sourceFile.getFullText() !== textBeforeRename) {\n return true\n }\n }\n\n element.replaceWithText(`${newName}: ${propertyName}${initializerText}`)\n return true\n}\n\nfunction getPropertyNameText({ node }: { node: Node }): string | undefined {\n if (Node.isIdentifier(node)) {\n return node.getText()\n }\n\n if (Node.isStringLiteral(node)) {\n return node.getLiteralValue()\n }\n\n return undefined\n}\n\nfunction containsIdentifierNamed({ name, node }: { name: string; node: Node }): boolean {\n return node\n .getDescendantsOfKind(SyntaxKind.Identifier)\n .some((identifier) => identifier.getText() === name)\n}\n\n/**\n * Compares symbols so an inner variable that shadows the props parameter isn't mistaken for it.\n * Falls back to comparing names when the type checker can't resolve a symbol.\n */\nfunction isReferenceTo({\n declaration,\n identifier,\n}: {\n declaration: Identifier\n identifier: Identifier\n}): boolean {\n if (identifier.getText() !== declaration.getText()) {\n return false\n }\n\n const declarationSymbol = declaration.getSymbol()\n\n return !declarationSymbol || identifier.getSymbol() === declarationSymbol\n}\n\n/**\n * Flags old prop names that remain in a property position, e.g. a JSX attribute passing\n * `comparisonValue` to another component, or `Pick<Props, 'versionValue'>`. Local variables that\n * merely share the old name are left alone.\n */\nfunction collectLeftoverNotes({ sourceFile }: { sourceFile: SourceFile }): string[] {\n const notedLocations = new Set<string>()\n const notes: string[] = []\n const candidates = [\n ...sourceFile\n .getDescendantsOfKind(SyntaxKind.Identifier)\n .filter((identifier) => isPropertyNamePosition({ identifier })),\n ...sourceFile.getDescendantsOfKind(SyntaxKind.StringLiteral),\n ].sort((a, b) => a.getStart() - b.getStart())\n\n for (const candidate of candidates) {\n const oldName = Node.isStringLiteral(candidate)\n ? candidate.getLiteralValue()\n : candidate.getText()\n const newName = RENAMED_PROPS.get(oldName)\n const location = `${sourceFile.getFilePath()}:${candidate.getStartLineNumber()}`\n\n if (!newName || notedLocations.has(`${location}:${oldName}`)) {\n continue\n }\n\n notedLocations.add(`${location}:${oldName}`)\n notes.push(\n `${location}: \\`${oldName}\\` was not migrated. If it refers to a Diff component prop, rename it to \\`${newName}\\`.`,\n )\n }\n\n return notes\n}\n\nfunction isPropertyNamePosition({ identifier }: { identifier: Identifier }): boolean {\n const parent = identifier.getParent()\n\n if (Node.isShorthandPropertyAssignment(parent) || Node.isJsxAttribute(parent)) {\n return true\n }\n\n if (Node.isBindingElement(parent)) {\n const propertyNameNode = parent.getPropertyNameNode()\n\n return propertyNameNode ? propertyNameNode === identifier : !parent.getDotDotDotToken()\n }\n\n if (\n Node.isPropertyAccessExpression(parent) ||\n Node.isPropertyAssignment(parent) ||\n Node.isPropertySignature(parent)\n ) {\n return parent.getNameNode() === identifier\n }\n\n return false\n}\n"],"names":["Node","SyntaxKind","RENAMED_PROPS","Map","DIFF_TYPE_NAME_PATTERN","MAX_REWRITES_PER_FILE","renameDiffValueProps","name","apply","project","filesChanged","notes","sourceFile","getSourceFiles","isDeclarationFile","isInNodeModules","diffTypeNames","collectDiffTypeNames","size","rewriteCount","rewriteNextOccurrence","push","getFilePath","collectLeftoverNotes","length","description","Set","importDeclaration","getImportDeclarations","getModuleSpecifierValue","namedImport","getNamedImports","test","getName","add","getAliasNode","getText","hasFoundNewName","derivedTypeNames","getTypeAliases","filter","typeAlias","referencesDiffType","typeNode","getTypeNodeOrThrow","getInterfaces","declaration","getExtends","some","heritage","has","getExpression","map","typeName","component","findDiffComponents","propsParameterName","getParameters","getNameNode","propsBindingPatterns","propsIdentifiers","isObjectBindingPattern","restElementName","getElements","find","element","getDotDotDotToken","isIdentifier","readsProps","node","propsIdentifier","isReferenceTo","identifier","getDescendantsOfKind","VariableDeclaration","declarationName","initializer","getInitializer","pattern","rewriteBindingElement","access","PropertyAccessExpression","newName","get","replaceWithText","ElementAccessExpression","argument","getArgumentExpression","isStringLiteral","getLiteralValue","setLiteralValue","indexedAccess","IndexedAccessType","indexType","getIndexTypeNode","literal","isLiteralTypeNode","getLiteral","undefined","getObjectTypeNode","functions","ArrowFunction","FunctionDeclaration","FunctionExpression","propsParameter","parent","getParent","typeNodes","getTypeNode","isVariableDeclaration","TypeReference","isTypeReference","getTypeName","isWrappedWithin","root","stopAt","ancestor","isPropertySignature","isIndexedAccessTypeNode","nameNode","propertyNameNode","getPropertyNameNode","propertyName","getPropertyNameText","initializerText","localName","containsIdentifierNamed","getSourceFile","textBeforeRename","getFullText","rename","usePrefixAndSuffixText","Identifier","declarationSymbol","getSymbol","notedLocations","candidates","isPropertyNamePosition","StringLiteral","sort","a","b","getStart","candidate","oldName","location","getStartLineNumber","isShorthandPropertyAssignment","isJsxAttribute","isBindingElement","isPropertyAccessExpression","isPropertyAssignment"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const isUnchanged = ({ comparisonValue, versionValue })=>comparisonValue === versionValue;
|
|
2
|
+
export const TextField = (props)=>props.versionValue;
|
|
3
|
+
export const versionValueField = {
|
|
4
|
+
name: 'versionValue',
|
|
5
|
+
type: 'text'
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=no-match.input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/transforms/rename-diff-value-props/no-match.input.ts"],"sourcesContent":["import type { Field, TextFieldClientProps } from 'payload'\n\ntype Comparison = { comparisonValue: unknown; versionValue: unknown }\n\nexport const isUnchanged = ({ comparisonValue, versionValue }: Comparison) =>\n comparisonValue === versionValue\n\nexport const TextField = (props: TextFieldClientProps & Comparison) => props.versionValue\n\nexport const versionValueField: Field = { name: 'versionValue', type: 'text' }\n"],"names":["isUnchanged","comparisonValue","versionValue","TextField","props","versionValueField","name","type"],"mappings":"AAIA,OAAO,MAAMA,cAAc,CAAC,EAAEC,eAAe,EAAEC,YAAY,EAAc,GACvED,oBAAoBC,aAAY;AAElC,OAAO,MAAMC,YAAY,CAACC,QAA6CA,MAAMF,YAAY,CAAA;AAEzF,OAAO,MAAMG,oBAA2B;IAAEC,MAAM;IAAgBC,MAAM;AAAO,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transforms/rename-experimental-table-feature/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transforms/rename-experimental-table-feature/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAM/C,eAAO,MAAM,8BAA8B,EAAE,SAkD5C,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Node } from 'ts-morph';
|
|
1
2
|
const PACKAGE_NAME = '@payloadcms/richtext-lexical';
|
|
2
3
|
const OLD_NAME = 'EXPERIMENTAL_TableFeature';
|
|
3
4
|
const NEW_NAME = 'TableFeature';
|
|
@@ -27,7 +28,12 @@ export const renameExperimentalTableFeature = {
|
|
|
27
28
|
} else {
|
|
28
29
|
// No alias: the imported name is also the local binding, so rename it to update
|
|
29
30
|
// every call site (e.g. `EXPERIMENTAL_TableFeature()`) in the same pass.
|
|
30
|
-
spec.getNameNode()
|
|
31
|
+
const nameNode = spec.getNameNode();
|
|
32
|
+
// Always an Identifier in valid code: a string-literal import name requires an alias.
|
|
33
|
+
if (!Node.isIdentifier(nameNode)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
nameNode.rename(NEW_NAME);
|
|
31
37
|
}
|
|
32
38
|
filesChanged.add(file.getFilePath());
|
|
33
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/transforms/rename-experimental-table-feature/index.ts"],"sourcesContent":["import type { Transform } from '../../types.js'\n\nconst PACKAGE_NAME = '@payloadcms/richtext-lexical'\nconst OLD_NAME = 'EXPERIMENTAL_TableFeature'\nconst NEW_NAME = 'TableFeature'\n\nexport const renameExperimentalTableFeature: Transform = {\n name: 'rename-experimental-table-feature',\n apply: ({ project }) => {\n const filesChanged = new Set<string>()\n\n for (const file of project.getSourceFiles()) {\n for (const importDecl of file.getImportDeclarations()) {\n if (importDecl.getModuleSpecifierValue() !== PACKAGE_NAME) {\n continue\n }\n\n const named = importDecl.getNamedImports()\n const spec = named.find((specifier) => specifier.getName() === OLD_NAME)\n if (!spec) {\n continue\n }\n\n // Skip if `TableFeature` is already imported here too, to avoid a collision.\n const hasNewName = named.some(\n (specifier) => (specifier.getAliasNode()?.getText() ?? specifier.getName()) === NEW_NAME,\n )\n if (hasNewName) {\n continue\n }\n\n if (spec.getAliasNode()) {\n // Aliased usages (`EXPERIMENTAL_TableFeature as Foo`) only reference the alias,\n // so the imported name can be swapped without touching call sites.\n spec.setName(NEW_NAME)\n } else {\n // No alias: the imported name is also the local binding, so rename it to update\n // every call site (e.g. `EXPERIMENTAL_TableFeature()`) in the same pass.\n spec.getNameNode().rename(NEW_NAME)\n }\n\n filesChanged.add(file.getFilePath())\n }\n }\n\n return { filesChanged: [...filesChanged] }\n },\n description:\n 'Renames imports of `EXPERIMENTAL_TableFeature` from `@payloadcms/richtext-lexical` to `TableFeature` (the table feature is now stable) and updates all local usages.',\n}\n"],"names":["PACKAGE_NAME","OLD_NAME","NEW_NAME","renameExperimentalTableFeature","name","apply","project","filesChanged","Set","file","getSourceFiles","importDecl","getImportDeclarations","getModuleSpecifierValue","named","getNamedImports","spec","find","specifier","getName","hasNewName","some","getAliasNode","getText","setName","getNameNode","rename","add","getFilePath","description"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/transforms/rename-experimental-table-feature/index.ts"],"sourcesContent":["import { Node } from 'ts-morph'\n\nimport type { Transform } from '../../types.js'\n\nconst PACKAGE_NAME = '@payloadcms/richtext-lexical'\nconst OLD_NAME = 'EXPERIMENTAL_TableFeature'\nconst NEW_NAME = 'TableFeature'\n\nexport const renameExperimentalTableFeature: Transform = {\n name: 'rename-experimental-table-feature',\n apply: ({ project }) => {\n const filesChanged = new Set<string>()\n\n for (const file of project.getSourceFiles()) {\n for (const importDecl of file.getImportDeclarations()) {\n if (importDecl.getModuleSpecifierValue() !== PACKAGE_NAME) {\n continue\n }\n\n const named = importDecl.getNamedImports()\n const spec = named.find((specifier) => specifier.getName() === OLD_NAME)\n if (!spec) {\n continue\n }\n\n // Skip if `TableFeature` is already imported here too, to avoid a collision.\n const hasNewName = named.some(\n (specifier) => (specifier.getAliasNode()?.getText() ?? specifier.getName()) === NEW_NAME,\n )\n if (hasNewName) {\n continue\n }\n\n if (spec.getAliasNode()) {\n // Aliased usages (`EXPERIMENTAL_TableFeature as Foo`) only reference the alias,\n // so the imported name can be swapped without touching call sites.\n spec.setName(NEW_NAME)\n } else {\n // No alias: the imported name is also the local binding, so rename it to update\n // every call site (e.g. `EXPERIMENTAL_TableFeature()`) in the same pass.\n const nameNode = spec.getNameNode()\n\n // Always an Identifier in valid code: a string-literal import name requires an alias.\n if (!Node.isIdentifier(nameNode)) {\n continue\n }\n\n nameNode.rename(NEW_NAME)\n }\n\n filesChanged.add(file.getFilePath())\n }\n }\n\n return { filesChanged: [...filesChanged] }\n },\n description:\n 'Renames imports of `EXPERIMENTAL_TableFeature` from `@payloadcms/richtext-lexical` to `TableFeature` (the table feature is now stable) and updates all local usages.',\n}\n"],"names":["Node","PACKAGE_NAME","OLD_NAME","NEW_NAME","renameExperimentalTableFeature","name","apply","project","filesChanged","Set","file","getSourceFiles","importDecl","getImportDeclarations","getModuleSpecifierValue","named","getNamedImports","spec","find","specifier","getName","hasNewName","some","getAliasNode","getText","setName","nameNode","getNameNode","isIdentifier","rename","add","getFilePath","description"],"mappings":"AAAA,SAASA,IAAI,QAAQ,WAAU;AAI/B,MAAMC,eAAe;AACrB,MAAMC,WAAW;AACjB,MAAMC,WAAW;AAEjB,OAAO,MAAMC,iCAA4C;IACvDC,MAAM;IACNC,OAAO,CAAC,EAAEC,OAAO,EAAE;QACjB,MAAMC,eAAe,IAAIC;QAEzB,KAAK,MAAMC,QAAQH,QAAQI,cAAc,GAAI;YAC3C,KAAK,MAAMC,cAAcF,KAAKG,qBAAqB,GAAI;gBACrD,IAAID,WAAWE,uBAAuB,OAAOb,cAAc;oBACzD;gBACF;gBAEA,MAAMc,QAAQH,WAAWI,eAAe;gBACxC,MAAMC,OAAOF,MAAMG,IAAI,CAAC,CAACC,YAAcA,UAAUC,OAAO,OAAOlB;gBAC/D,IAAI,CAACe,MAAM;oBACT;gBACF;gBAEA,6EAA6E;gBAC7E,MAAMI,aAAaN,MAAMO,IAAI,CAC3B,CAACH,YAAc,AAACA,CAAAA,UAAUI,YAAY,IAAIC,aAAaL,UAAUC,OAAO,EAAC,MAAOjB;gBAElF,IAAIkB,YAAY;oBACd;gBACF;gBAEA,IAAIJ,KAAKM,YAAY,IAAI;oBACvB,gFAAgF;oBAChF,mEAAmE;oBACnEN,KAAKQ,OAAO,CAACtB;gBACf,OAAO;oBACL,gFAAgF;oBAChF,yEAAyE;oBACzE,MAAMuB,WAAWT,KAAKU,WAAW;oBAEjC,sFAAsF;oBACtF,IAAI,CAAC3B,KAAK4B,YAAY,CAACF,WAAW;wBAChC;oBACF;oBAEAA,SAASG,MAAM,CAAC1B;gBAClB;gBAEAK,aAAasB,GAAG,CAACpB,KAAKqB,WAAW;YACnC;QACF;QAEA,OAAO;YAAEvB,cAAc;mBAAIA;aAAa;QAAC;IAC3C;IACAwB,aACE;AACJ,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewritePackageJson.d.ts","sourceRoot":"","sources":["../../src/upgrade/rewritePackageJson.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rewritePackageJson.d.ts","sourceRoot":"","sources":["../../src/upgrade/rewritePackageJson.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,QAAQ,EAAE,gBAAgB,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,mBAAmB,EAAE,MAAM,EAAE,CAAA;CAC9B,CAAA;AAOD,eAAO,MAAM,gBAAgB,SAAU,MAAM,KAAG,OACO,CAAA;AAEvD;;;GAGG;AACH,eAAO,MAAM,sBAAsB,SAAU,MAAM,KAAG,OACf,CAAA;AAEvC;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,SAAU,OAAO,KAAG,OACO,CAAA;AAEzD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,GAAG,cAAc,CAKlF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import semver from 'semver';
|
|
1
2
|
const DEP_FIELDS = [
|
|
2
3
|
'dependencies',
|
|
3
4
|
'devDependencies'
|
|
@@ -95,26 +96,66 @@ function pruneOverrideBlock(block, label, removed) {
|
|
|
95
96
|
}
|
|
96
97
|
function writeFloors(data, resolved) {
|
|
97
98
|
const written = [];
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
if (writeDepFloor({
|
|
100
|
+
name: 'typescript',
|
|
101
|
+
data,
|
|
102
|
+
floor: resolved.typescript
|
|
103
|
+
})) {
|
|
104
|
+
written.push('typescript');
|
|
105
|
+
}
|
|
106
|
+
if (writeDepFloor({
|
|
107
|
+
name: '@types/node',
|
|
108
|
+
data,
|
|
109
|
+
floor: resolved.typesNode
|
|
110
|
+
})) {
|
|
111
|
+
written.push('@types/node');
|
|
112
|
+
}
|
|
101
113
|
const engines = isRecord(data.engines) ? data.engines : {};
|
|
102
|
-
engines.node
|
|
103
|
-
|
|
104
|
-
|
|
114
|
+
if (engines.node === undefined || isBelowFloor({
|
|
115
|
+
floor: resolved.enginesNode,
|
|
116
|
+
spec: engines.node
|
|
117
|
+
})) {
|
|
118
|
+
engines.node = resolved.enginesNode;
|
|
119
|
+
data.engines = engines;
|
|
120
|
+
written.push('engines.node');
|
|
121
|
+
}
|
|
105
122
|
return written;
|
|
106
123
|
}
|
|
107
|
-
/**
|
|
124
|
+
/**
|
|
125
|
+
* Raise a dep to `floor` wherever it already lives, else add it to devDependencies.
|
|
126
|
+
* Placeholder specs, non-semver specs (e.g. `latest`), and ranges already at or
|
|
127
|
+
* above the floor are left as-is. Returns whether the dep was written.
|
|
128
|
+
*/ function writeDepFloor({ name, data, floor }) {
|
|
108
129
|
for (const field of DEP_FIELDS){
|
|
109
130
|
const deps = data[field];
|
|
110
|
-
if (isRecord(deps)
|
|
111
|
-
|
|
112
|
-
|
|
131
|
+
if (!isRecord(deps) || !(name in deps)) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const spec = deps[name];
|
|
135
|
+
if (isPlaceholderSpec(spec) || !isBelowFloor({
|
|
136
|
+
floor,
|
|
137
|
+
spec
|
|
138
|
+
})) {
|
|
139
|
+
return false;
|
|
113
140
|
}
|
|
141
|
+
deps[name] = floor;
|
|
142
|
+
return true;
|
|
114
143
|
}
|
|
115
144
|
const devDeps = isRecord(data.devDependencies) ? data.devDependencies : {};
|
|
116
|
-
devDeps[name] =
|
|
145
|
+
devDeps[name] = floor;
|
|
117
146
|
data.devDependencies = devDeps;
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
/** True only when `spec` is a semver range whose lowest version is below the floor's. */ function isBelowFloor({ floor, spec }) {
|
|
150
|
+
if (typeof spec !== 'string' || !semver.validRange(spec)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
const specMin = semver.minVersion(spec);
|
|
154
|
+
const floorMin = semver.minVersion(floor);
|
|
155
|
+
if (!specMin || !floorMin) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
return semver.lt(specMin, floorMin);
|
|
118
159
|
}
|
|
119
160
|
function isRecord(value) {
|
|
120
161
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|