@akinon/projectzero 2.0.15-beta.0 → 2.0.15
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/CHANGELOG.md
CHANGED
|
@@ -1,37 +1,36 @@
|
|
|
1
1
|
# projectzeronext
|
|
2
2
|
|
|
3
|
-
## 2.0.15
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- @akinon/pz-tamara-extension@2.0.15-beta.0
|
|
3
|
+
## 2.0.15
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @akinon/next@2.0.15
|
|
8
|
+
- @akinon/pz-akifast@2.0.15
|
|
9
|
+
- @akinon/pz-apple-pay@2.0.15
|
|
10
|
+
- @akinon/pz-b2b@2.0.15
|
|
11
|
+
- @akinon/pz-basket-gift-pack@2.0.15
|
|
12
|
+
- @akinon/pz-bkm@2.0.15
|
|
13
|
+
- @akinon/pz-checkout-gift-pack@2.0.15
|
|
14
|
+
- @akinon/pz-click-collect@2.0.15
|
|
15
|
+
- @akinon/pz-credit-payment@2.0.15
|
|
16
|
+
- @akinon/pz-cybersource-uc@2.0.15
|
|
17
|
+
- @akinon/pz-flow-payment@2.0.15
|
|
18
|
+
- @akinon/pz-google-pay@2.0.15
|
|
19
|
+
- @akinon/pz-gpay@2.0.15
|
|
20
|
+
- @akinon/pz-haso@2.0.15
|
|
21
|
+
- @akinon/pz-hepsipay@2.0.15
|
|
22
|
+
- @akinon/pz-masterpass@2.0.15
|
|
23
|
+
- @akinon/pz-masterpass-rest@2.0.15
|
|
24
|
+
- @akinon/pz-multi-basket@2.0.15
|
|
25
|
+
- @akinon/pz-one-click-checkout@2.0.15
|
|
26
|
+
- @akinon/pz-otp@2.0.15
|
|
27
|
+
- @akinon/pz-pay-on-delivery@2.0.15
|
|
28
|
+
- @akinon/pz-saved-card@2.0.15
|
|
29
|
+
- @akinon/pz-similar-products@2.0.15
|
|
30
|
+
- @akinon/pz-tabby-extension@2.0.15
|
|
31
|
+
- @akinon/pz-tamara-extension@2.0.15
|
|
32
|
+
- @akinon/pz-theme@2.0.15
|
|
33
|
+
- @akinon/pz-virtual-try-on@2.0.15
|
|
35
34
|
|
|
36
35
|
## 2.0.14
|
|
37
36
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projectzeronext",
|
|
3
|
-
"version": "2.0.15
|
|
3
|
+
"version": "2.0.15",
|
|
4
4
|
"private": true,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"scripts": {
|
|
@@ -24,33 +24,33 @@
|
|
|
24
24
|
"test:middleware": "jest middleware-matcher.test.ts --bail"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@akinon/next": "2.0.15
|
|
28
|
-
"@akinon/pz-akifast": "2.0.15
|
|
29
|
-
"@akinon/pz-apple-pay": "2.0.15
|
|
30
|
-
"@akinon/pz-b2b": "2.0.15
|
|
31
|
-
"@akinon/pz-basket-gift-pack": "2.0.15
|
|
32
|
-
"@akinon/pz-bkm": "2.0.15
|
|
33
|
-
"@akinon/pz-checkout-gift-pack": "2.0.15
|
|
34
|
-
"@akinon/pz-click-collect": "2.0.15
|
|
35
|
-
"@akinon/pz-credit-payment": "2.0.15
|
|
36
|
-
"@akinon/pz-cybersource-uc": "2.0.15
|
|
37
|
-
"@akinon/pz-flow-payment": "2.0.15
|
|
38
|
-
"@akinon/pz-google-pay": "2.0.15
|
|
39
|
-
"@akinon/pz-gpay": "2.0.15
|
|
40
|
-
"@akinon/pz-haso": "2.0.15
|
|
41
|
-
"@akinon/pz-hepsipay": "2.0.15
|
|
42
|
-
"@akinon/pz-masterpass": "2.0.15
|
|
43
|
-
"@akinon/pz-masterpass-rest": "2.0.15
|
|
44
|
-
"@akinon/pz-multi-basket": "2.0.15
|
|
45
|
-
"@akinon/pz-one-click-checkout": "2.0.15
|
|
46
|
-
"@akinon/pz-otp": "2.0.15
|
|
47
|
-
"@akinon/pz-pay-on-delivery": "2.0.15
|
|
48
|
-
"@akinon/pz-saved-card": "2.0.15
|
|
49
|
-
"@akinon/pz-similar-products": "2.0.15
|
|
50
|
-
"@akinon/pz-tabby-extension": "2.0.15
|
|
51
|
-
"@akinon/pz-tamara-extension": "2.0.15
|
|
52
|
-
"@akinon/pz-theme": "2.0.15
|
|
53
|
-
"@akinon/pz-virtual-try-on": "2.0.15
|
|
27
|
+
"@akinon/next": "2.0.15",
|
|
28
|
+
"@akinon/pz-akifast": "2.0.15",
|
|
29
|
+
"@akinon/pz-apple-pay": "2.0.15",
|
|
30
|
+
"@akinon/pz-b2b": "2.0.15",
|
|
31
|
+
"@akinon/pz-basket-gift-pack": "2.0.15",
|
|
32
|
+
"@akinon/pz-bkm": "2.0.15",
|
|
33
|
+
"@akinon/pz-checkout-gift-pack": "2.0.15",
|
|
34
|
+
"@akinon/pz-click-collect": "2.0.15",
|
|
35
|
+
"@akinon/pz-credit-payment": "2.0.15",
|
|
36
|
+
"@akinon/pz-cybersource-uc": "2.0.15",
|
|
37
|
+
"@akinon/pz-flow-payment": "2.0.15",
|
|
38
|
+
"@akinon/pz-google-pay": "2.0.15",
|
|
39
|
+
"@akinon/pz-gpay": "2.0.15",
|
|
40
|
+
"@akinon/pz-haso": "2.0.15",
|
|
41
|
+
"@akinon/pz-hepsipay": "2.0.15",
|
|
42
|
+
"@akinon/pz-masterpass": "2.0.15",
|
|
43
|
+
"@akinon/pz-masterpass-rest": "2.0.15",
|
|
44
|
+
"@akinon/pz-multi-basket": "2.0.15",
|
|
45
|
+
"@akinon/pz-one-click-checkout": "2.0.15",
|
|
46
|
+
"@akinon/pz-otp": "2.0.15",
|
|
47
|
+
"@akinon/pz-pay-on-delivery": "2.0.15",
|
|
48
|
+
"@akinon/pz-saved-card": "2.0.15",
|
|
49
|
+
"@akinon/pz-similar-products": "2.0.15",
|
|
50
|
+
"@akinon/pz-tabby-extension": "2.0.15",
|
|
51
|
+
"@akinon/pz-tamara-extension": "2.0.15",
|
|
52
|
+
"@akinon/pz-theme": "2.0.15",
|
|
53
|
+
"@akinon/pz-virtual-try-on": "2.0.15",
|
|
54
54
|
"@hookform/resolvers": "2.9.0",
|
|
55
55
|
"@next/third-parties": "16.2.6",
|
|
56
56
|
"@react-google-maps/api": "2.17.1",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"yup": "0.32.11"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
|
-
"@akinon/eslint-plugin-projectzero": "2.0.15
|
|
77
|
+
"@akinon/eslint-plugin-projectzero": "2.0.15",
|
|
78
78
|
"@semantic-release/changelog": "6.0.2",
|
|
79
79
|
"@semantic-release/exec": "6.0.3",
|
|
80
80
|
"@semantic-release/git": "10.0.1",
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* migrate-page-types: rewrites `PageProps<T>` from `@akinon/next/types` into
|
|
3
|
+
* `AsyncPageProps<T>` / `ResolvedPageProps<T>` across a brand's `src/`.
|
|
4
|
+
*
|
|
5
|
+
* Why: `@next/codemod next-async-request-api` updates the call sites
|
|
6
|
+
* (`await props.params`, `use(props.params)`), but the @akinon/next legacy
|
|
7
|
+
* `PageProps<T>` type is still sync and clashes with Next 16's internal
|
|
8
|
+
* `.next/types/.../page.ts` validator. Manually fixing every brand on every
|
|
9
|
+
* upgrade is the same change repeated — this codemod automates it.
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* cd <brand-root>
|
|
13
|
+
* npx @akinon/projectzero codemod --codemod=migrate-page-types [--dry-run]
|
|
14
|
+
*
|
|
15
|
+
* Or via the upgrade-to-2 chain (no flag needed).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const path = require('path');
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const jscodeshift = require('jscodeshift/src/Runner');
|
|
21
|
+
|
|
22
|
+
function log(msg) {
|
|
23
|
+
const ts = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
24
|
+
console.log(`[${ts}] [migrate-page-types] ${msg}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const transform = () => {
|
|
28
|
+
const workingDir = path.resolve(process.cwd());
|
|
29
|
+
const dryRun = process.argv.includes('--dry-run');
|
|
30
|
+
|
|
31
|
+
log(`starting in ${workingDir}${dryRun ? ' (DRY RUN)' : ''}`);
|
|
32
|
+
|
|
33
|
+
const srcDir = path.join(workingDir, 'src');
|
|
34
|
+
if (!fs.existsSync(srcDir)) {
|
|
35
|
+
log('No src/ directory found, nothing to migrate.');
|
|
36
|
+
return Promise.resolve();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const transformPath = path.resolve(__dirname, 'transform.js');
|
|
40
|
+
|
|
41
|
+
return jscodeshift
|
|
42
|
+
.run(transformPath, [srcDir], {
|
|
43
|
+
verbose: 0,
|
|
44
|
+
dry: Boolean(dryRun),
|
|
45
|
+
print: Boolean(dryRun),
|
|
46
|
+
extensions: 'ts,tsx',
|
|
47
|
+
parser: 'tsx',
|
|
48
|
+
ignorePattern: '**/node_modules/**',
|
|
49
|
+
silent: true
|
|
50
|
+
})
|
|
51
|
+
.then(
|
|
52
|
+
(stats) => {
|
|
53
|
+
log(
|
|
54
|
+
`${stats.ok} changed, ${stats.nochange} unchanged, ${stats.error} errored`
|
|
55
|
+
);
|
|
56
|
+
log('done');
|
|
57
|
+
},
|
|
58
|
+
(err) => {
|
|
59
|
+
log(`FAILED: ${err.message}`);
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
module.exports = { transform };
|
|
66
|
+
|
|
67
|
+
if (require.main === module) {
|
|
68
|
+
const result = transform();
|
|
69
|
+
if (result && typeof result.then === 'function') {
|
|
70
|
+
result.catch((err) => {
|
|
71
|
+
console.error(err);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* jscodeshift transform: rewrite `PageProps<T>` from `@akinon/next/types`
|
|
3
|
+
* into `AsyncPageProps<T>` or `ResolvedPageProps<T>` per usage context.
|
|
4
|
+
*
|
|
5
|
+
* Heuristic per occurrence:
|
|
6
|
+
* - Enclosing function is `generateMetadata` → AsyncPageProps
|
|
7
|
+
* - Body uses `await props.params` / `await props.searchParams` or
|
|
8
|
+
* `use(props.params)` / `use(props.searchParams)` → AsyncPageProps
|
|
9
|
+
* - Otherwise (destructured params accessed synchronously, typical Page
|
|
10
|
+
* wrapped in `withSegmentDefaults`) → ResolvedPageProps
|
|
11
|
+
*
|
|
12
|
+
* Import is rewritten: PageProps removed, AsyncPageProps / ResolvedPageProps
|
|
13
|
+
* added as needed, sorted alphabetically (matches prettier output).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const TARGET_IMPORT = '@akinon/next/types';
|
|
17
|
+
|
|
18
|
+
function getEnclosingFunction(path) {
|
|
19
|
+
let cur = path;
|
|
20
|
+
while (cur.parent) {
|
|
21
|
+
cur = cur.parent;
|
|
22
|
+
const t = cur.node && cur.node.type;
|
|
23
|
+
if (
|
|
24
|
+
t === 'FunctionDeclaration' ||
|
|
25
|
+
t === 'FunctionExpression' ||
|
|
26
|
+
t === 'ArrowFunctionExpression'
|
|
27
|
+
) {
|
|
28
|
+
return cur;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getFunctionName(fnPath) {
|
|
35
|
+
const node = fnPath.node;
|
|
36
|
+
if (node.id && node.id.name) return node.id.name;
|
|
37
|
+
let p = fnPath.parent;
|
|
38
|
+
while (p) {
|
|
39
|
+
const t = p.node && p.node.type;
|
|
40
|
+
if (t === 'VariableDeclarator' && p.node.id && p.node.id.name) {
|
|
41
|
+
return p.node.id.name;
|
|
42
|
+
}
|
|
43
|
+
if (
|
|
44
|
+
t === 'Property' ||
|
|
45
|
+
t === 'ObjectProperty' ||
|
|
46
|
+
t === 'MethodDefinition'
|
|
47
|
+
) {
|
|
48
|
+
const key = p.node.key;
|
|
49
|
+
if (key && key.name) return key.name;
|
|
50
|
+
}
|
|
51
|
+
if (
|
|
52
|
+
t === 'FunctionDeclaration' ||
|
|
53
|
+
t === 'FunctionExpression' ||
|
|
54
|
+
t === 'ArrowFunctionExpression'
|
|
55
|
+
) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
p = p.parent;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function bodyUsesAsyncResolve(fnPath, j) {
|
|
64
|
+
let found = false;
|
|
65
|
+
const isParamsMember = (node) =>
|
|
66
|
+
node &&
|
|
67
|
+
node.type === 'MemberExpression' &&
|
|
68
|
+
node.property &&
|
|
69
|
+
(node.property.name === 'params' ||
|
|
70
|
+
node.property.name === 'searchParams');
|
|
71
|
+
|
|
72
|
+
j(fnPath)
|
|
73
|
+
.find(j.AwaitExpression)
|
|
74
|
+
.forEach((awaitPath) => {
|
|
75
|
+
if (isParamsMember(awaitPath.node.argument)) found = true;
|
|
76
|
+
});
|
|
77
|
+
j(fnPath)
|
|
78
|
+
.find(j.CallExpression, { callee: { name: 'use' } })
|
|
79
|
+
.forEach((callPath) => {
|
|
80
|
+
const arg = callPath.node.arguments && callPath.node.arguments[0];
|
|
81
|
+
if (isParamsMember(arg)) found = true;
|
|
82
|
+
});
|
|
83
|
+
return found;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function transform(fileInfo, api) {
|
|
87
|
+
const j = api.jscodeshift;
|
|
88
|
+
const root = j(fileInfo.source);
|
|
89
|
+
|
|
90
|
+
const akinonImports = root.find(j.ImportDeclaration, {
|
|
91
|
+
source: { value: TARGET_IMPORT }
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (akinonImports.length === 0) return null;
|
|
95
|
+
|
|
96
|
+
let hasPageProps = false;
|
|
97
|
+
akinonImports.forEach((imp) => {
|
|
98
|
+
const specs = imp.node.specifiers || [];
|
|
99
|
+
if (
|
|
100
|
+
specs.some(
|
|
101
|
+
(s) =>
|
|
102
|
+
s.type === 'ImportSpecifier' &&
|
|
103
|
+
s.imported &&
|
|
104
|
+
s.imported.name === 'PageProps'
|
|
105
|
+
)
|
|
106
|
+
) {
|
|
107
|
+
hasPageProps = true;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (!hasPageProps) return null;
|
|
112
|
+
|
|
113
|
+
let usedAsync = false;
|
|
114
|
+
let usedResolved = false;
|
|
115
|
+
|
|
116
|
+
root
|
|
117
|
+
.find(j.TSTypeReference, {
|
|
118
|
+
typeName: { type: 'Identifier', name: 'PageProps' }
|
|
119
|
+
})
|
|
120
|
+
.forEach((path) => {
|
|
121
|
+
const fnPath = getEnclosingFunction(path);
|
|
122
|
+
let target = 'AsyncPageProps';
|
|
123
|
+
if (fnPath) {
|
|
124
|
+
const fnName = getFunctionName(fnPath);
|
|
125
|
+
if (fnName === 'generateMetadata') {
|
|
126
|
+
target = 'AsyncPageProps';
|
|
127
|
+
} else if (bodyUsesAsyncResolve(fnPath, j)) {
|
|
128
|
+
target = 'AsyncPageProps';
|
|
129
|
+
} else {
|
|
130
|
+
target = 'ResolvedPageProps';
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
path.node.typeName = j.identifier(target);
|
|
134
|
+
if (target === 'AsyncPageProps') usedAsync = true;
|
|
135
|
+
else usedResolved = true;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
akinonImports.forEach((imp) => {
|
|
139
|
+
const specs = imp.node.specifiers || [];
|
|
140
|
+
const existingNames = new Set(
|
|
141
|
+
specs
|
|
142
|
+
.filter((s) => s.type === 'ImportSpecifier' && s.imported)
|
|
143
|
+
.map((s) => s.imported.name)
|
|
144
|
+
);
|
|
145
|
+
const next = specs.filter(
|
|
146
|
+
(s) =>
|
|
147
|
+
!(
|
|
148
|
+
s.type === 'ImportSpecifier' &&
|
|
149
|
+
s.imported &&
|
|
150
|
+
s.imported.name === 'PageProps'
|
|
151
|
+
)
|
|
152
|
+
);
|
|
153
|
+
if (usedAsync && !existingNames.has('AsyncPageProps')) {
|
|
154
|
+
next.push(j.importSpecifier(j.identifier('AsyncPageProps')));
|
|
155
|
+
}
|
|
156
|
+
if (usedResolved && !existingNames.has('ResolvedPageProps')) {
|
|
157
|
+
next.push(j.importSpecifier(j.identifier('ResolvedPageProps')));
|
|
158
|
+
}
|
|
159
|
+
next.sort((a, b) => {
|
|
160
|
+
if (a.type !== 'ImportSpecifier' || b.type !== 'ImportSpecifier') return 0;
|
|
161
|
+
return a.imported.name.localeCompare(b.imported.name);
|
|
162
|
+
});
|
|
163
|
+
imp.node.specifiers = next;
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
return root.toSource({ quote: 'single' });
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
module.exports = transform;
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
* 6. Run migrate-auth-v5 codemod (next-auth v4 -> v5)
|
|
12
12
|
* 7. Run sentry-9 codemod (only when @sentry/nextjs is present)
|
|
13
13
|
* 8. Run migrate-eslint codemod (ESLint v9 flat config)
|
|
14
|
-
* 9.
|
|
15
|
-
* 10.
|
|
14
|
+
* 9. Run migrate-page-types codemod (PageProps -> Async/Resolved)
|
|
15
|
+
* 10. yarn build (validation)
|
|
16
|
+
* 11. Summary report
|
|
16
17
|
*
|
|
17
18
|
* Out of scope in this first version:
|
|
18
19
|
* - Tailwind v3 -> v4 migration (run manually with @tailwindcss/upgrade)
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
* --skip-auth Do not run migrate-auth-v5
|
|
33
34
|
* --skip-sentry Do not run sentry-9 (auto-skipped if not needed)
|
|
34
35
|
* --skip-eslint Do not run migrate-eslint
|
|
36
|
+
* --skip-page-types Do not run migrate-page-types
|
|
35
37
|
* --skip-install Do not run yarn install
|
|
36
38
|
* --skip-build Do not run yarn build
|
|
37
39
|
* --interactive Pause for confirmation after each step
|
|
@@ -46,6 +48,7 @@ const readline = require('readline');
|
|
|
46
48
|
const AUTH_CODEMOD = path.resolve(__dirname, '..', 'migrate-auth-v5');
|
|
47
49
|
const SENTRY_CODEMOD = path.resolve(__dirname, '..', 'sentry-9');
|
|
48
50
|
const ESLINT_CODEMOD = path.resolve(__dirname, '..', 'migrate-eslint');
|
|
51
|
+
const PAGE_TYPES_CODEMOD = path.resolve(__dirname, '..', 'migrate-page-types');
|
|
49
52
|
|
|
50
53
|
const TARGET_MATRIX = {
|
|
51
54
|
dependencies: {
|
|
@@ -134,6 +137,7 @@ function parseArgs(argv) {
|
|
|
134
137
|
skipAuth: argv.includes('--skip-auth'),
|
|
135
138
|
skipSentry: argv.includes('--skip-sentry'),
|
|
136
139
|
skipEslint: argv.includes('--skip-eslint'),
|
|
140
|
+
skipPageTypes: argv.includes('--skip-page-types'),
|
|
137
141
|
skipInstall: argv.includes('--skip-install'),
|
|
138
142
|
skipBuild: argv.includes('--skip-build'),
|
|
139
143
|
interactive: argv.includes('--interactive'),
|
|
@@ -154,7 +158,7 @@ function writePackageJson(cwd, pkg) {
|
|
|
154
158
|
}
|
|
155
159
|
|
|
156
160
|
function stepPreflight(cwd, flags) {
|
|
157
|
-
logStep('[1/
|
|
161
|
+
logStep('[1/11] Preflight', 'starting');
|
|
158
162
|
|
|
159
163
|
const pkg = readPackageJson(cwd);
|
|
160
164
|
if (!pkg) {
|
|
@@ -188,19 +192,19 @@ function stepPreflight(cwd, flags) {
|
|
|
188
192
|
log(` Current: next@${currentNext} react@${currentReact} next-auth@${currentAuth} @akinon/next@${currentAkinon}`);
|
|
189
193
|
log(` Target: next@${TARGET_MATRIX.dependencies.next} react@${TARGET_MATRIX.dependencies.react} next-auth@${TARGET_MATRIX.dependencies['next-auth']} @akinon/next@${TARGET_MATRIX.dependencies['@akinon/next']}`);
|
|
190
194
|
|
|
191
|
-
logStep('[1/
|
|
195
|
+
logStep('[1/11] Preflight', 'ok');
|
|
192
196
|
}
|
|
193
197
|
|
|
194
198
|
function stepBackup(cwd, flags) {
|
|
195
199
|
if (flags.skipBackup) {
|
|
196
|
-
logStep('[2/
|
|
200
|
+
logStep('[2/11] Backup branch', 'skipped');
|
|
197
201
|
return null;
|
|
198
202
|
}
|
|
199
203
|
const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
|
|
200
204
|
const branchName = `pre-upgrade-2-${today}`;
|
|
201
205
|
|
|
202
206
|
if (flags.dryRun) {
|
|
203
|
-
logStep('[2/
|
|
207
|
+
logStep('[2/11] Backup branch', `[DRY] git branch ${branchName}`);
|
|
204
208
|
return branchName;
|
|
205
209
|
}
|
|
206
210
|
|
|
@@ -210,7 +214,7 @@ function stepBackup(cwd, flags) {
|
|
|
210
214
|
{ cwd, encoding: 'utf-8' }
|
|
211
215
|
);
|
|
212
216
|
if (existing.status === 0) {
|
|
213
|
-
logStep('[2/
|
|
217
|
+
logStep('[2/11] Backup branch', `already exists: ${branchName}`);
|
|
214
218
|
return branchName;
|
|
215
219
|
}
|
|
216
220
|
|
|
@@ -221,7 +225,7 @@ function stepBackup(cwd, flags) {
|
|
|
221
225
|
if (result.status !== 0) {
|
|
222
226
|
throw new Error(`Failed to create backup branch ${branchName}`);
|
|
223
227
|
}
|
|
224
|
-
logStep('[2/
|
|
228
|
+
logStep('[2/11] Backup branch', `created ${branchName}`);
|
|
225
229
|
return branchName;
|
|
226
230
|
}
|
|
227
231
|
|
|
@@ -319,7 +323,7 @@ function pinNextScriptsToWebpack(pkg) {
|
|
|
319
323
|
|
|
320
324
|
function stepBump(cwd, flags) {
|
|
321
325
|
if (flags.skipBump) {
|
|
322
|
-
logStep('[3/
|
|
326
|
+
logStep('[3/11] Bump deps', 'skipped');
|
|
323
327
|
return { hasSentry: false, changes: [] };
|
|
324
328
|
}
|
|
325
329
|
|
|
@@ -367,16 +371,16 @@ function stepBump(cwd, flags) {
|
|
|
367
371
|
allChanges.push(...scriptChanges);
|
|
368
372
|
|
|
369
373
|
if (allChanges.length === 0) {
|
|
370
|
-
logStep('[3/
|
|
374
|
+
logStep('[3/11] Bump deps', 'already at target, no changes');
|
|
371
375
|
return { hasSentry, changes: [] };
|
|
372
376
|
}
|
|
373
377
|
|
|
374
378
|
if (flags.dryRun) {
|
|
375
|
-
logStep('[3/
|
|
379
|
+
logStep('[3/11] Bump deps', `[DRY] ${allChanges.length} changes`);
|
|
376
380
|
allChanges.forEach((c) => log(` - ${c}`));
|
|
377
381
|
} else {
|
|
378
382
|
writePackageJson(cwd, pkg);
|
|
379
|
-
logStep('[3/
|
|
383
|
+
logStep('[3/11] Bump deps', `${allChanges.length} changes applied`);
|
|
380
384
|
if (flags.verbose) allChanges.forEach((c) => log(` - ${c}`));
|
|
381
385
|
}
|
|
382
386
|
|
|
@@ -385,28 +389,28 @@ function stepBump(cwd, flags) {
|
|
|
385
389
|
|
|
386
390
|
function stepNextCodemod(cwd, flags) {
|
|
387
391
|
if (flags.skipNextCodemod) {
|
|
388
|
-
logStep('[5/
|
|
392
|
+
logStep('[5/11] Next codemod', 'skipped');
|
|
389
393
|
return { ok: true };
|
|
390
394
|
}
|
|
391
395
|
const cmd = flags.dryRun
|
|
392
396
|
? 'npx --yes @next/codemod@latest upgrade latest --verbose'
|
|
393
397
|
: 'npx --yes @next/codemod@latest upgrade latest';
|
|
394
|
-
logStep('[5/
|
|
398
|
+
logStep('[5/11] Next codemod', `running ${cmd}`);
|
|
395
399
|
const result = runCommand(cmd, { cwd, dryRun: false, verbose: flags.verbose });
|
|
396
400
|
if (result.status !== 0) {
|
|
397
|
-
logStep('[5/
|
|
401
|
+
logStep('[5/11] Next codemod', `FAILED (exit ${result.status})`);
|
|
398
402
|
return { ok: false };
|
|
399
403
|
}
|
|
400
|
-
logStep('[5/
|
|
404
|
+
logStep('[5/11] Next codemod', 'ok');
|
|
401
405
|
return { ok: true };
|
|
402
406
|
}
|
|
403
407
|
|
|
404
408
|
function stepAuthCodemod(cwd, flags) {
|
|
405
409
|
if (flags.skipAuth) {
|
|
406
|
-
logStep('[6/
|
|
410
|
+
logStep('[6/11] Auth codemod', 'skipped');
|
|
407
411
|
return { ok: true };
|
|
408
412
|
}
|
|
409
|
-
logStep('[6/
|
|
413
|
+
logStep('[6/11] Auth codemod', 'running migrate-auth-v5');
|
|
410
414
|
try {
|
|
411
415
|
const prevArgv = process.argv;
|
|
412
416
|
process.argv = [
|
|
@@ -426,21 +430,21 @@ function stepAuthCodemod(cwd, flags) {
|
|
|
426
430
|
return result.then(
|
|
427
431
|
() => {
|
|
428
432
|
finish();
|
|
429
|
-
logStep('[6/
|
|
433
|
+
logStep('[6/11] Auth codemod', 'ok');
|
|
430
434
|
return { ok: true };
|
|
431
435
|
},
|
|
432
436
|
(err) => {
|
|
433
437
|
finish();
|
|
434
|
-
logStep('[6/
|
|
438
|
+
logStep('[6/11] Auth codemod', `FAILED: ${err.message}`);
|
|
435
439
|
return { ok: false };
|
|
436
440
|
}
|
|
437
441
|
);
|
|
438
442
|
}
|
|
439
443
|
finish();
|
|
440
|
-
logStep('[6/
|
|
444
|
+
logStep('[6/11] Auth codemod', 'ok');
|
|
441
445
|
return { ok: true };
|
|
442
446
|
} catch (err) {
|
|
443
|
-
logStep('[6/
|
|
447
|
+
logStep('[6/11] Auth codemod', `FAILED: ${err.message}`);
|
|
444
448
|
return { ok: false };
|
|
445
449
|
}
|
|
446
450
|
}
|
|
@@ -448,34 +452,34 @@ function stepAuthCodemod(cwd, flags) {
|
|
|
448
452
|
function stepSentryCodemod(cwd, flags, hasSentry) {
|
|
449
453
|
if (flags.skipSentry || !hasSentry) {
|
|
450
454
|
const reason = flags.skipSentry ? 'skipped' : 'no @sentry/nextjs, skipping';
|
|
451
|
-
logStep('[7/
|
|
455
|
+
logStep('[7/11] Sentry codemod', reason);
|
|
452
456
|
return { ok: true };
|
|
453
457
|
}
|
|
454
458
|
if (flags.dryRun) {
|
|
455
|
-
logStep('[7/
|
|
459
|
+
logStep('[7/11] Sentry codemod', '[DRY] would run sentry-9');
|
|
456
460
|
return { ok: true };
|
|
457
461
|
}
|
|
458
|
-
logStep('[7/
|
|
462
|
+
logStep('[7/11] Sentry codemod', 'running sentry-9');
|
|
459
463
|
try {
|
|
460
464
|
const savedCwd = process.cwd();
|
|
461
465
|
process.chdir(cwd);
|
|
462
466
|
const codemod = require(SENTRY_CODEMOD);
|
|
463
467
|
codemod.transform();
|
|
464
468
|
process.chdir(savedCwd);
|
|
465
|
-
logStep('[7/
|
|
469
|
+
logStep('[7/11] Sentry codemod', 'ok');
|
|
466
470
|
return { ok: true };
|
|
467
471
|
} catch (err) {
|
|
468
|
-
logStep('[7/
|
|
472
|
+
logStep('[7/11] Sentry codemod', `FAILED: ${err.message}`);
|
|
469
473
|
return { ok: false };
|
|
470
474
|
}
|
|
471
475
|
}
|
|
472
476
|
|
|
473
477
|
function stepEslintCodemod(cwd, flags) {
|
|
474
478
|
if (flags.skipEslint) {
|
|
475
|
-
logStep('[8/
|
|
479
|
+
logStep('[8/11] ESLint codemod', 'skipped');
|
|
476
480
|
return { ok: true };
|
|
477
481
|
}
|
|
478
|
-
logStep('[8/
|
|
482
|
+
logStep('[8/11] ESLint codemod', 'running migrate-eslint');
|
|
479
483
|
try {
|
|
480
484
|
const prevArgv = process.argv;
|
|
481
485
|
process.argv = [
|
|
@@ -489,24 +493,68 @@ function stepEslintCodemod(cwd, flags) {
|
|
|
489
493
|
codemod.transform();
|
|
490
494
|
process.chdir(savedCwd);
|
|
491
495
|
process.argv = prevArgv;
|
|
492
|
-
logStep('[8/
|
|
496
|
+
logStep('[8/11] ESLint codemod', 'ok');
|
|
493
497
|
return { ok: true };
|
|
494
498
|
} catch (err) {
|
|
495
|
-
logStep('[8/
|
|
499
|
+
logStep('[8/11] ESLint codemod', `FAILED: ${err.message}`);
|
|
500
|
+
return { ok: false };
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function stepPageTypesCodemod(cwd, flags) {
|
|
505
|
+
if (flags.skipPageTypes) {
|
|
506
|
+
logStep('[9/11] Page types codemod', 'skipped');
|
|
507
|
+
return { ok: true };
|
|
508
|
+
}
|
|
509
|
+
logStep('[9/11] Page types codemod', 'running migrate-page-types');
|
|
510
|
+
try {
|
|
511
|
+
const prevArgv = process.argv;
|
|
512
|
+
process.argv = [
|
|
513
|
+
process.argv[0],
|
|
514
|
+
process.argv[1],
|
|
515
|
+
...(flags.dryRun ? ['--dry-run'] : [])
|
|
516
|
+
];
|
|
517
|
+
const savedCwd = process.cwd();
|
|
518
|
+
process.chdir(cwd);
|
|
519
|
+
const codemod = require(PAGE_TYPES_CODEMOD);
|
|
520
|
+
const result = codemod.transform();
|
|
521
|
+
const finish = () => {
|
|
522
|
+
process.chdir(savedCwd);
|
|
523
|
+
process.argv = prevArgv;
|
|
524
|
+
};
|
|
525
|
+
if (result && typeof result.then === 'function') {
|
|
526
|
+
return result.then(
|
|
527
|
+
() => {
|
|
528
|
+
finish();
|
|
529
|
+
logStep('[9/11] Page types codemod', 'ok');
|
|
530
|
+
return { ok: true };
|
|
531
|
+
},
|
|
532
|
+
(err) => {
|
|
533
|
+
finish();
|
|
534
|
+
logStep('[9/11] Page types codemod', `FAILED: ${err.message}`);
|
|
535
|
+
return { ok: false };
|
|
536
|
+
}
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
finish();
|
|
540
|
+
logStep('[9/11] Page types codemod', 'ok');
|
|
541
|
+
return { ok: true };
|
|
542
|
+
} catch (err) {
|
|
543
|
+
logStep('[9/11] Page types codemod', `FAILED: ${err.message}`);
|
|
496
544
|
return { ok: false };
|
|
497
545
|
}
|
|
498
546
|
}
|
|
499
547
|
|
|
500
548
|
function stepInstall(cwd, flags) {
|
|
501
549
|
if (flags.skipInstall) {
|
|
502
|
-
logStep('[4/
|
|
550
|
+
logStep('[4/11] yarn install', 'skipped');
|
|
503
551
|
return { ok: true };
|
|
504
552
|
}
|
|
505
553
|
if (flags.dryRun) {
|
|
506
|
-
logStep('[4/
|
|
554
|
+
logStep('[4/11] yarn install', '[DRY] yarn clean && yarn');
|
|
507
555
|
return { ok: true };
|
|
508
556
|
}
|
|
509
|
-
logStep('[4/
|
|
557
|
+
logStep('[4/11] yarn install', 'running yarn clean && yarn');
|
|
510
558
|
const clean = runCommand('yarn clean', {
|
|
511
559
|
cwd,
|
|
512
560
|
dryRun: false,
|
|
@@ -521,33 +569,33 @@ function stepInstall(cwd, flags) {
|
|
|
521
569
|
verbose: flags.verbose
|
|
522
570
|
});
|
|
523
571
|
if (install.status !== 0) {
|
|
524
|
-
logStep('[4/
|
|
572
|
+
logStep('[4/11] yarn install', `FAILED (exit ${install.status})`);
|
|
525
573
|
return { ok: false };
|
|
526
574
|
}
|
|
527
|
-
logStep('[4/
|
|
575
|
+
logStep('[4/11] yarn install', 'ok');
|
|
528
576
|
return { ok: true };
|
|
529
577
|
}
|
|
530
578
|
|
|
531
579
|
function stepBuild(cwd, flags) {
|
|
532
580
|
if (flags.skipBuild) {
|
|
533
|
-
logStep('[
|
|
581
|
+
logStep('[10/11] yarn build', 'skipped');
|
|
534
582
|
return { ok: true };
|
|
535
583
|
}
|
|
536
584
|
if (flags.dryRun) {
|
|
537
|
-
logStep('[
|
|
585
|
+
logStep('[10/11] yarn build', '[DRY] yarn build');
|
|
538
586
|
return { ok: true };
|
|
539
587
|
}
|
|
540
|
-
logStep('[
|
|
588
|
+
logStep('[10/11] yarn build', 'running');
|
|
541
589
|
const result = runCommand('yarn build', {
|
|
542
590
|
cwd,
|
|
543
591
|
dryRun: false,
|
|
544
592
|
verbose: flags.verbose
|
|
545
593
|
});
|
|
546
594
|
if (result.status !== 0) {
|
|
547
|
-
logStep('[
|
|
595
|
+
logStep('[10/11] yarn build', `FAILED (exit ${result.status})`);
|
|
548
596
|
return { ok: false };
|
|
549
597
|
}
|
|
550
|
-
logStep('[
|
|
598
|
+
logStep('[10/11] yarn build', 'ok');
|
|
551
599
|
return { ok: true };
|
|
552
600
|
}
|
|
553
601
|
|
|
@@ -559,7 +607,7 @@ function countTodoMarkers(cwd) {
|
|
|
559
607
|
}
|
|
560
608
|
|
|
561
609
|
function stepReport(cwd, results) {
|
|
562
|
-
logStep('[
|
|
610
|
+
logStep('[11/11] Report', 'summary');
|
|
563
611
|
const pkg = readPackageJson(cwd) || {};
|
|
564
612
|
const todoCount = countTodoMarkers(cwd);
|
|
565
613
|
|
|
@@ -572,6 +620,7 @@ function stepReport(cwd, results) {
|
|
|
572
620
|
console.log(` Auth codemod: ${results.authCodemod ? 'ok' : 'FAILED'}`);
|
|
573
621
|
console.log(` Sentry codemod: ${results.sentryCodemod ? 'ok' : results.sentrySkippedReason || 'FAILED'}`);
|
|
574
622
|
console.log(` ESLint codemod: ${results.eslintCodemod ? 'ok' : 'FAILED'}`);
|
|
623
|
+
console.log(` Page types: ${results.pageTypesCodemod ? 'ok' : 'FAILED'}`);
|
|
575
624
|
console.log(` Build: ${results.build ? 'ok' : 'FAILED'}`);
|
|
576
625
|
console.log('');
|
|
577
626
|
console.log(` Versions after:`);
|
|
@@ -618,7 +667,7 @@ async function transform() {
|
|
|
618
667
|
results.preflight = true;
|
|
619
668
|
await maybePause(flags, 'preflight');
|
|
620
669
|
} else {
|
|
621
|
-
logStep('[1/
|
|
670
|
+
logStep('[1/11] Preflight', 'skipped');
|
|
622
671
|
results.preflight = true;
|
|
623
672
|
}
|
|
624
673
|
|
|
@@ -652,6 +701,14 @@ async function transform() {
|
|
|
652
701
|
results.eslintCodemod = stepEslintCodemod(cwd, flags).ok;
|
|
653
702
|
await maybePause(flags, 'eslint-codemod');
|
|
654
703
|
|
|
704
|
+
const pageTypesResult = stepPageTypesCodemod(cwd, flags);
|
|
705
|
+
const pageTypesAwaited =
|
|
706
|
+
pageTypesResult && typeof pageTypesResult.then === 'function'
|
|
707
|
+
? await pageTypesResult
|
|
708
|
+
: pageTypesResult;
|
|
709
|
+
results.pageTypesCodemod = pageTypesAwaited.ok;
|
|
710
|
+
await maybePause(flags, 'page-types-codemod');
|
|
711
|
+
|
|
655
712
|
results.build = stepBuild(cwd, flags).ok;
|
|
656
713
|
} catch (err) {
|
|
657
714
|
log(`FATAL: ${err.message}`);
|