@payloadcms/codemod 4.0.0-internal.cd47d20 → 4.0.0-internal.ce66a41

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.
Files changed (58) hide show
  1. package/README.md +3 -1
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.help.d.ts +4 -0
  4. package/dist/cli.help.d.ts.map +1 -0
  5. package/dist/cli.help.js +29 -0
  6. package/dist/cli.help.js.map +1 -0
  7. package/dist/cli.js +8 -0
  8. package/dist/cli.js.map +1 -1
  9. package/dist/cli.parseFlags.d.ts +1 -0
  10. package/dist/cli.parseFlags.d.ts.map +1 -1
  11. package/dist/cli.parseFlags.js +6 -0
  12. package/dist/cli.parseFlags.js.map +1 -1
  13. package/dist/registry.js +2 -2
  14. package/dist/registry.js.map +1 -1
  15. package/dist/runbook/v4.mdx +134 -21
  16. package/dist/transforms/migrate-field-component-types/index.d.ts.map +1 -1
  17. package/dist/transforms/migrate-field-component-types/index.js +4 -0
  18. package/dist/transforms/migrate-field-component-types/index.js.map +1 -1
  19. package/dist/transforms/migrate-sharp-to-transformer/basic.input.js +28 -0
  20. package/dist/transforms/migrate-sharp-to-transformer/basic.input.js.map +1 -0
  21. package/dist/transforms/migrate-sharp-to-transformer/basic.output.js +39 -0
  22. package/dist/transforms/migrate-sharp-to-transformer/basic.output.js.map +1 -0
  23. package/dist/transforms/migrate-sharp-to-transformer/existing-transformers.input.js +27 -0
  24. package/dist/transforms/migrate-sharp-to-transformer/existing-transformers.input.js.map +1 -0
  25. package/dist/transforms/migrate-sharp-to-transformer/existing-transformers.output.js +33 -0
  26. package/dist/transforms/migrate-sharp-to-transformer/existing-transformers.output.js.map +1 -0
  27. package/dist/transforms/migrate-sharp-to-transformer/index.d.ts +3 -0
  28. package/dist/transforms/migrate-sharp-to-transformer/index.d.ts.map +1 -0
  29. package/dist/transforms/migrate-sharp-to-transformer/index.js +430 -0
  30. package/dist/transforms/migrate-sharp-to-transformer/index.js.map +1 -0
  31. package/dist/transforms/migrate-sharp-to-transformer/no-match.input.js +11 -0
  32. package/dist/transforms/migrate-sharp-to-transformer/no-match.input.js.map +1 -0
  33. package/dist/transforms/migrate-sharp-to-transformer/no-match.output.js +11 -0
  34. package/dist/transforms/migrate-sharp-to-transformer/no-match.output.js.map +1 -0
  35. package/dist/transforms/remove-storage-always-insert-fields/index.d.ts.map +1 -1
  36. package/dist/transforms/remove-storage-always-insert-fields/index.js +4 -0
  37. package/dist/transforms/remove-storage-always-insert-fields/index.js.map +1 -1
  38. package/dist/transforms/rename-experimental-table-feature/index.d.ts.map +1 -1
  39. package/dist/transforms/rename-experimental-table-feature/index.js +7 -1
  40. package/dist/transforms/rename-experimental-table-feature/index.js.map +1 -1
  41. package/dist/upgrade/rewritePackageJson.d.ts.map +1 -1
  42. package/dist/upgrade/rewritePackageJson.js +52 -11
  43. package/dist/upgrade/rewritePackageJson.js.map +1 -1
  44. package/dist/utils/project.d.ts +7 -1
  45. package/dist/utils/project.d.ts.map +1 -1
  46. package/dist/utils/project.js +20 -7
  47. package/dist/utils/project.js.map +1 -1
  48. package/package.json +2 -2
  49. package/dist/transforms/remove-strict-draft-types/basic.input.js +0 -28
  50. package/dist/transforms/remove-strict-draft-types/basic.input.js.map +0 -1
  51. package/dist/transforms/remove-strict-draft-types/basic.output.js +0 -24
  52. package/dist/transforms/remove-strict-draft-types/basic.output.js.map +0 -1
  53. package/dist/transforms/remove-strict-draft-types/index.d.ts +0 -3
  54. package/dist/transforms/remove-strict-draft-types/index.d.ts.map +0 -1
  55. package/dist/transforms/remove-strict-draft-types/index.js +0 -44
  56. package/dist/transforms/remove-strict-draft-types/index.js.map +0 -1
  57. package/dist/transforms/remove-strict-draft-types/no-match.input.js +0 -11
  58. package/dist/transforms/remove-strict-draft-types/no-match.input.js.map +0 -1
@@ -0,0 +1,430 @@
1
+ import { Node, SyntaxKind } from 'ts-morph';
2
+ const TRANSFORMER_MODULE = '@payloadcms/transformer-sharp';
3
+ const TRANSFORMER_NAME = 'sharpTransformer';
4
+ const VARIANTS_KEY = 'variants';
5
+ const IDENTIFIER_PATTERN = /^[A-Z_$][\w$]*$/i;
6
+ /** Whether `value` can be used as a plain (unquoted, non-bracketed) object literal key. */ function isSafePlainObjectKey(value) {
7
+ return IDENTIFIER_PATTERN.test(value);
8
+ }
9
+ /** Fields moved from a collection's `upload` object into `sharpTransformer({ collections })`. */ const MOVED_UPLOAD_FIELDS = [
10
+ 'constructorOptions',
11
+ 'formatOptions',
12
+ 'resizeOptions',
13
+ 'trimOptions',
14
+ 'withMetadata',
15
+ 'imageSizes',
16
+ 'crop',
17
+ 'focalPoint'
18
+ ];
19
+ const findBuildConfigLocalNames = (file)=>{
20
+ const localNames = new Set();
21
+ for (const importDecl of file.getImportDeclarations()){
22
+ if (importDecl.getModuleSpecifierValue() !== 'payload') {
23
+ continue;
24
+ }
25
+ for (const spec of importDecl.getNamedImports()){
26
+ if (spec.getName() === 'buildConfig') {
27
+ localNames.add(spec.getAliasNode()?.getText() ?? spec.getName());
28
+ }
29
+ }
30
+ }
31
+ return localNames;
32
+ };
33
+ /**
34
+ * Resolves the local binding of the imported `sharpTransformer`, honoring an alias such as
35
+ * `import { sharpTransformer as st }`. When it isn't imported yet, picks a name no other
36
+ * identifier in the file uses, so a local `sharpTransformer` function is never mistaken for it.
37
+ */ function resolveSharpTransformerBinding(sourceFile) {
38
+ const namedImports = sourceFile.getImportDeclarations().filter((decl)=>decl.getModuleSpecifierValue() === TRANSFORMER_MODULE && !decl.isTypeOnly()).flatMap((decl)=>decl.getNamedImports()).filter((named)=>named.getName() === TRANSFORMER_NAME && !named.isTypeOnly());
39
+ const unaliasedImport = namedImports.find((named)=>!named.getAliasNode());
40
+ const aliasedImport = namedImports.find((named)=>named.getAliasNode());
41
+ if (unaliasedImport) {
42
+ return {
43
+ isImported: true,
44
+ localName: TRANSFORMER_NAME
45
+ };
46
+ }
47
+ if (aliasedImport) {
48
+ return {
49
+ isImported: true,
50
+ localName: aliasedImport.getAliasNode().getText()
51
+ };
52
+ }
53
+ const usedIdentifiers = new Set(sourceFile.getDescendantsOfKind(SyntaxKind.Identifier).map((identifier)=>identifier.getText()));
54
+ let localName = TRANSFORMER_NAME;
55
+ for(let suffix = 2; usedIdentifiers.has(localName); suffix++){
56
+ localName = `${TRANSFORMER_NAME}${suffix}`;
57
+ }
58
+ return {
59
+ isImported: false,
60
+ localName
61
+ };
62
+ }
63
+ function ensureSharpTransformerImport({ localName, sourceFile }) {
64
+ const namedImport = localName === TRANSFORMER_NAME ? TRANSFORMER_NAME : {
65
+ name: TRANSFORMER_NAME,
66
+ alias: localName
67
+ };
68
+ const existing = sourceFile.getImportDeclarations().find((decl)=>decl.getModuleSpecifierValue() === TRANSFORMER_MODULE && !decl.isTypeOnly());
69
+ if (!existing) {
70
+ const otherImports = sourceFile.getImportDeclarations();
71
+ const fileOmitsSemicolonsOnImports = otherImports.length > 0 && otherImports.every((decl)=>!decl.getText().endsWith(';'));
72
+ const insertedImport = sourceFile.addImportDeclaration({
73
+ moduleSpecifier: TRANSFORMER_MODULE,
74
+ namedImports: [
75
+ namedImport
76
+ ]
77
+ });
78
+ // ts-morph always appends a semicolon; strip it when the file's other imports don't use them.
79
+ if (fileOmitsSemicolonsOnImports) {
80
+ const insertedImportText = insertedImport.getText();
81
+ if (insertedImportText.endsWith(';')) {
82
+ insertedImport.replaceWithText(insertedImportText.slice(0, -1));
83
+ }
84
+ }
85
+ return;
86
+ }
87
+ const alreadyImported = existing.getNamedImports().some((named)=>named.getName() === TRANSFORMER_NAME && !named.isTypeOnly() && (named.getAliasNode()?.getText() ?? TRANSFORMER_NAME) === localName);
88
+ if (!alreadyImported) {
89
+ existing.addNamedImport(namedImport);
90
+ }
91
+ }
92
+ /**
93
+ * Reads Sharp-owned fields off one collection's `upload` object literal into
94
+ * a `<slug>: { ... }` entry text for the `sharpTransformer({ collections })` map,
95
+ * without modifying the collection. Returns `undefined` when the collection has nothing to migrate.
96
+ */ function extractCollectionSharpEntry({ collectionObj, configFile, notes }) {
97
+ const filePath = collectionObj.getSourceFile().getFilePath();
98
+ const isExternal = collectionObj.getSourceFile() !== configFile;
99
+ const slugProp = collectionObj.getProperty('slug');
100
+ const slugAssignment = slugProp?.asKind(SyntaxKind.PropertyAssignment);
101
+ const slugInitializer = slugAssignment?.getInitializer();
102
+ if (!slugInitializer) {
103
+ return undefined;
104
+ }
105
+ const uploadProp = collectionObj.getProperty('upload');
106
+ if (!uploadProp || !Node.isPropertyAssignment(uploadProp)) {
107
+ return undefined;
108
+ }
109
+ const uploadObj = uploadProp.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
110
+ if (!uploadObj) {
111
+ if (uploadProp.getInitializer()?.getKind() !== SyntaxKind.TrueKeyword) {
112
+ notes.push(`${filePath}: collection ${slugInitializer.getText()}'s \`upload\` option is not an inline object — check it for Sharp-specific fields (resizeOptions/imageSizes/formatOptions/trimOptions/constructorOptions/withMetadata/crop/focalPoint) manually.`);
113
+ }
114
+ return undefined;
115
+ }
116
+ const uploadHasSpread = uploadObj.getProperties().some((prop)=>Node.isSpreadAssignment(prop));
117
+ if (uploadHasSpread) {
118
+ notes.push(`${filePath}: collection ${slugInitializer.getText()}'s \`upload\` object contains a spread — Sharp-specific fields (resizeOptions/imageSizes/formatOptions/trimOptions/constructorOptions/withMetadata/crop/focalPoint) hidden inside it need manual review.`);
119
+ }
120
+ const movedTexts = [];
121
+ const movedProps = [];
122
+ for (const name of MOVED_UPLOAD_FIELDS){
123
+ const prop = uploadObj.getProperty(name);
124
+ if (!prop) {
125
+ continue;
126
+ }
127
+ // A shorthand `imageSizes` reads the same binding from `buildConfig`'s argument,
128
+ // where the `sharpTransformer` call is inserted, so it moves verbatim.
129
+ if (Node.isPropertyAssignment(prop) || Node.isShorthandPropertyAssignment(prop)) {
130
+ const localReference = isExternal ? findLocalReference({
131
+ node: prop
132
+ }) : undefined;
133
+ // Moving the text into the config file would leave this reference unresolved there.
134
+ if (localReference) {
135
+ notes.push(`${filePath}: collection ${slugInitializer.getText()}'s \`upload.${name}\` refers to \`${localReference.getText()}\`, which isn't available in ${configFile.getFilePath()} — move this collection's Sharp-specific \`upload\` fields into \`sharpTransformer({ collections })\` manually.`);
136
+ return undefined;
137
+ }
138
+ movedTexts.push(name === 'imageSizes' ? printAsVariants(prop) : prop.print());
139
+ movedProps.push(prop);
140
+ continue;
141
+ }
142
+ notes.push(`${filePath}: collection ${slugInitializer.getText()}'s \`upload.${name}\` isn't a plain property — move it into \`sharpTransformer({ collections })\` manually.`);
143
+ }
144
+ if (movedTexts.length === 0) {
145
+ return undefined;
146
+ }
147
+ const slugLiteralValue = getSlugLiteralValue({
148
+ isExternal,
149
+ slugInitializer
150
+ });
151
+ if (isExternal && slugLiteralValue === undefined) {
152
+ notes.push(`${filePath}: collection ${slugInitializer.getText()}'s slug isn't a string constant — move its Sharp-specific \`upload\` fields into \`sharpTransformer({ collections })\` manually.`);
153
+ return undefined;
154
+ }
155
+ // A slug constant from another file isn't in scope in the config file, so it's keyed by value.
156
+ const keyText = slugLiteralValue !== undefined && isSafePlainObjectKey(slugLiteralValue) ? slugLiteralValue : isExternal && !isStringLiteralNode(slugInitializer) ? `'${slugLiteralValue.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'` : `[${slugInitializer.getText()}]`;
157
+ return {
158
+ entryText: `${keyText}: { ${movedTexts.join(', ')} }`,
159
+ movedProps,
160
+ uploadObj
161
+ };
162
+ }
163
+ function isStringLiteralNode(node) {
164
+ return Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node);
165
+ }
166
+ /**
167
+ * A slug written as a string literal or, for a collection in another file, a constant whose
168
+ * type is a string literal (e.g. `slug: mediaSlug` with `const mediaSlug = 'media'`).
169
+ */ function getSlugLiteralValue({ isExternal, slugInitializer }) {
170
+ if (isStringLiteralNode(slugInitializer)) {
171
+ return slugInitializer.getLiteralValue();
172
+ }
173
+ if (!isExternal) {
174
+ return undefined;
175
+ }
176
+ const slugType = slugInitializer.getType();
177
+ return slugType.isStringLiteral() ? slugType.getLiteralValue() : undefined;
178
+ }
179
+ /**
180
+ * The first identifier inside `node` bound to a declaration elsewhere in the project, such as an
181
+ * import or a local variable. Declarations inside `node` itself (parameters, its own property
182
+ * names) and ambient/library ones (`undefined`, `Math`) don't count.
183
+ */ function findLocalReference({ node }) {
184
+ const sourceFile = node.getSourceFile();
185
+ return node.getDescendantsOfKind(SyntaxKind.Identifier).find((identifier)=>(identifier.getSymbol()?.getDeclarations() ?? []).some((declaration)=>{
186
+ const declarationFile = declaration.getSourceFile();
187
+ if (declarationFile.isDeclarationFile() || declarationFile.isFromExternalLibrary()) {
188
+ return false;
189
+ }
190
+ return declarationFile !== sourceFile || declaration.getPos() < node.getPos() || declaration.getEnd() > node.getEnd();
191
+ }));
192
+ }
193
+ /**
194
+ * Follows a `collections` array element written as an identifier (usually an imported
195
+ * collection, e.g. `import { Media } from './collections/Media'`) to the object literal it's
196
+ * declared as, unwrapping `satisfies`/`as`/parentheses. Returns `undefined` for anything else,
197
+ * such as a factory call.
198
+ */ function resolveCollectionObject({ expression }) {
199
+ let current = expression;
200
+ for(let depth = 0; current && depth < 5; depth++){
201
+ while(Node.isSatisfiesExpression(current) || Node.isAsExpression(current) || Node.isParenthesizedExpression(current)){
202
+ current = current.getExpression();
203
+ }
204
+ if (Node.isObjectLiteralExpression(current)) {
205
+ return current;
206
+ }
207
+ if (!Node.isIdentifier(current)) {
208
+ return undefined;
209
+ }
210
+ const symbol = current.getSymbol();
211
+ const declaration = (symbol?.isAlias() ? symbol.getAliasedSymbol() : symbol)?.getDeclarations()[0];
212
+ if (Node.isVariableDeclaration(declaration)) {
213
+ current = declaration.getInitializer();
214
+ } else if (Node.isExportAssignment(declaration)) {
215
+ current = declaration.getExpression();
216
+ } else {
217
+ return undefined;
218
+ }
219
+ }
220
+ return undefined;
221
+ }
222
+ function removeMovedCollectionProps({ movedProps, uploadObj }) {
223
+ for (const prop of movedProps){
224
+ prop.remove();
225
+ }
226
+ // Avoid leaving `upload: {\n}` spread across two lines once every property moves out.
227
+ if (uploadObj.getProperties().length === 0) {
228
+ uploadObj.replaceWithText('{}');
229
+ }
230
+ }
231
+ /**
232
+ * Builds every `<slug>: { ... }` entry for a `buildConfig({ collections })` array,
233
+ * skipping (and, for a present `sharp` signal, noting) entries that aren't inline
234
+ * object literals or whose `collections` array isn't statically analyzable.
235
+ */ function extractSharpCollectionEntries({ configObj, notes }) {
236
+ const configFile = configObj.getSourceFile();
237
+ const filePath = configFile.getFilePath();
238
+ const collectionsProp = configObj.getProperty('collections');
239
+ if (!collectionsProp || !Node.isPropertyAssignment(collectionsProp)) {
240
+ return [];
241
+ }
242
+ const arrayLiteral = collectionsProp.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression);
243
+ if (!arrayLiteral) {
244
+ notes.push(`${filePath}: \`collections\` isn't an inline array — check each collection for Sharp-specific \`upload\` fields (resizeOptions/imageSizes/formatOptions/trimOptions/constructorOptions/withMetadata/crop/focalPoint) and move them into \`sharpTransformer({ collections })\` manually.`);
245
+ return [];
246
+ }
247
+ const entries = [];
248
+ for (const el of arrayLiteral.getElements()){
249
+ const collectionObj = resolveCollectionObject({
250
+ expression: el
251
+ });
252
+ if (!collectionObj) {
253
+ notes.push(`${filePath}: a collection in \`collections\` (\`${el.getText()}\`) is defined externally — check it for Sharp-specific \`upload\` fields and move them into \`sharpTransformer({ collections })\` manually.`);
254
+ continue;
255
+ }
256
+ const entry = extractCollectionSharpEntry({
257
+ collectionObj,
258
+ configFile,
259
+ notes
260
+ });
261
+ if (entry) {
262
+ entries.push(entry);
263
+ }
264
+ }
265
+ return entries;
266
+ }
267
+ /** `sharpTransformer` authors image sizes as `variants`; the collection's `imageSizes` is renamed on the way in. */ function printAsVariants(prop) {
268
+ return Node.isShorthandPropertyAssignment(prop) ? `${VARIANTS_KEY}: ${prop.getName()}` : `${VARIANTS_KEY}: ${prop.getInitializerOrThrow().print()}`;
269
+ }
270
+ /**
271
+ * Renames `imageSizes` to `variants` inside every inline `sharpTransformer({ collections })`
272
+ * entry in the file — configs migrated before `variants` existed. Returns whether it changed
273
+ * anything.
274
+ */ function renameImageSizesInSharpTransformerCalls({ notes, sourceFile, transformerLocalName }) {
275
+ let hasChanged = false;
276
+ const sharpTransformerCalls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).filter((call)=>{
277
+ const callee = call.getExpression();
278
+ return Node.isIdentifier(callee) && callee.getText() === transformerLocalName;
279
+ });
280
+ for (const call of sharpTransformerCalls){
281
+ const collectionsObj = call.getArguments()[0]?.asKind(SyntaxKind.ObjectLiteralExpression)?.getProperty('collections')?.asKind(SyntaxKind.PropertyAssignment)?.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
282
+ for (const entry of collectionsObj?.getProperties() ?? []){
283
+ const entryObj = Node.isPropertyAssignment(entry) ? entry.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression) : undefined;
284
+ if (!entryObj) {
285
+ notes.push(`${sourceFile.getFilePath()}: a \`${TRANSFORMER_NAME}({ collections })\` entry isn't an inline object — rename any \`imageSizes\` in it to \`${VARIANTS_KEY}\` manually.`);
286
+ continue;
287
+ }
288
+ const imageSizesProp = entryObj.getProperty('imageSizes');
289
+ if (imageSizesProp && Node.isPropertyAssignment(imageSizesProp)) {
290
+ imageSizesProp.getNameNode().replaceWithText(VARIANTS_KEY);
291
+ hasChanged = true;
292
+ } else if (imageSizesProp && Node.isShorthandPropertyAssignment(imageSizesProp)) {
293
+ imageSizesProp.replaceWithText(printAsVariants(imageSizesProp));
294
+ hasChanged = true;
295
+ }
296
+ }
297
+ }
298
+ return hasChanged;
299
+ }
300
+ function findSharpTransformerCall({ transformerLocalName, transformersArray }) {
301
+ return transformersArray.getElements().find((el)=>{
302
+ if (!Node.isCallExpression(el)) {
303
+ return false;
304
+ }
305
+ const callee = el.getExpression();
306
+ return Node.isIdentifier(callee) && callee.getText() === transformerLocalName;
307
+ });
308
+ }
309
+ export const migrateSharpToTransformer = {
310
+ name: 'migrate-sharp-to-transformer',
311
+ apply: ({ project })=>{
312
+ const filesChanged = new Set();
313
+ const notes = [];
314
+ for (const sourceFile of project.getSourceFiles()){
315
+ const { isImported, localName: transformerLocalName } = resolveSharpTransformerBinding(sourceFile);
316
+ if (isImported && renameImageSizesInSharpTransformerCalls({
317
+ notes,
318
+ sourceFile,
319
+ transformerLocalName
320
+ })) {
321
+ filesChanged.add(sourceFile.getFilePath());
322
+ }
323
+ const buildConfigLocalNames = findBuildConfigLocalNames(sourceFile);
324
+ if (buildConfigLocalNames.size === 0) {
325
+ continue;
326
+ }
327
+ const calls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).filter((call)=>{
328
+ const expr = call.getExpression();
329
+ return Node.isIdentifier(expr) && buildConfigLocalNames.has(expr.getText());
330
+ });
331
+ for (const call of calls){
332
+ const [arg] = call.getArguments();
333
+ const configObj = arg?.asKind(SyntaxKind.ObjectLiteralExpression);
334
+ if (!configObj) {
335
+ notes.push(`${sourceFile.getFilePath()}: \`buildConfig\` argument is not an inline object literal — check it manually for a top-level \`sharp\` dependency and per-collection Sharp-specific \`upload\` options.`);
336
+ continue;
337
+ }
338
+ const uploadProp = configObj.getProperty('upload');
339
+ const uploadObj = uploadProp?.asKind(SyntaxKind.PropertyAssignment)?.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
340
+ const existingTransformersProp = uploadObj?.getProperty('transformers');
341
+ const existingTransformersArray = existingTransformersProp?.asKind(SyntaxKind.PropertyAssignment)?.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression);
342
+ if (existingTransformersArray && findSharpTransformerCall({
343
+ transformerLocalName,
344
+ transformersArray: existingTransformersArray
345
+ })) {
346
+ // Already migrated, but a leftover `sharp` property would fail a later
347
+ // type-check with no signal from this codemod — flag it here.
348
+ if (configObj.getProperty('sharp')) {
349
+ notes.push(`${sourceFile.getFilePath()}: a top-level \`sharp\` property remains even though \`sharpTransformer\` is already registered — move any value you still need into the existing \`sharpTransformer\` call, then remove \`sharp\` manually.`);
350
+ }
351
+ continue;
352
+ }
353
+ const sharpProp = configObj.getProperty('sharp');
354
+ let sharpExpressionText;
355
+ if (sharpProp && Node.isPropertyAssignment(sharpProp)) {
356
+ sharpExpressionText = sharpProp.getInitializer()?.getText();
357
+ } else if (sharpProp && Node.isShorthandPropertyAssignment(sharpProp)) {
358
+ sharpExpressionText = sharpProp.getName();
359
+ }
360
+ const collectionEntries = extractSharpCollectionEntries({
361
+ configObj,
362
+ notes
363
+ });
364
+ if (!sharpExpressionText && collectionEntries.length === 0) {
365
+ continue;
366
+ }
367
+ const transformerArgs = [];
368
+ if (sharpExpressionText) {
369
+ transformerArgs.push(sharpExpressionText === 'sharp' ? 'sharp' : `sharp: ${sharpExpressionText}`);
370
+ }
371
+ if (collectionEntries.length > 0) {
372
+ transformerArgs.push(`collections: { ${collectionEntries.map((entry)=>entry.entryText).join(', ')} }`);
373
+ }
374
+ const transformerCallText = `${transformerLocalName}({ ${transformerArgs.join(', ')} })`;
375
+ // Adding a `transformers` property next to a non-array one, or after a spread
376
+ // that may already set it, would create a duplicate key whose last value wins
377
+ // at runtime — silently dropping the existing transformers.
378
+ const uploadHasSpread = uploadObj?.getProperties().some((prop)=>Node.isSpreadAssignment(prop));
379
+ // The old settings are only removed once the replacement call is registered —
380
+ // otherwise the migrated config would silently lose its image processing.
381
+ let isRegistered = true;
382
+ if (existingTransformersArray) {
383
+ existingTransformersArray.addElement(transformerCallText);
384
+ } else if (existingTransformersProp) {
385
+ isRegistered = false;
386
+ notes.push(`${sourceFile.getFilePath()}: \`upload.transformers\` isn't an inline array — add \`${transformerCallText}\` to it manually, then remove the migrated Sharp settings.`);
387
+ } else if (uploadHasSpread) {
388
+ isRegistered = false;
389
+ notes.push(`${sourceFile.getFilePath()}: \`upload\` contains a spread that may already set \`transformers\` — add \`${transformerCallText}\` to its transformers manually, then remove the migrated Sharp settings.`);
390
+ } else if (uploadObj) {
391
+ uploadObj.addPropertyAssignment({
392
+ name: 'transformers',
393
+ initializer: `[${transformerCallText}]`
394
+ });
395
+ } else if (uploadProp) {
396
+ isRegistered = false;
397
+ notes.push(`${sourceFile.getFilePath()}: \`upload\` isn't an inline object — add \`transformers: [${transformerCallText}]\` to it manually, then remove the migrated Sharp settings.`);
398
+ } else {
399
+ configObj.addPropertyAssignment({
400
+ name: 'upload',
401
+ initializer: `{ transformers: [${transformerCallText}] }`
402
+ });
403
+ }
404
+ if (!isRegistered) {
405
+ continue;
406
+ }
407
+ sharpProp?.remove();
408
+ for (const entry of collectionEntries){
409
+ removeMovedCollectionProps(entry);
410
+ filesChanged.add(entry.uploadObj.getSourceFile().getFilePath());
411
+ }
412
+ ensureSharpTransformerImport({
413
+ localName: transformerLocalName,
414
+ sourceFile
415
+ });
416
+ filesChanged.add(sourceFile.getFilePath());
417
+ }
418
+ }
419
+ if (filesChanged.size > 0) {
420
+ notes.push(`Install the new dependency this migration relies on: pnpm add @payloadcms/transformer-sharp`);
421
+ }
422
+ return {
423
+ filesChanged: Array.from(filesChanged),
424
+ notes: notes.length ? notes : undefined
425
+ };
426
+ },
427
+ description: 'Move a top-level `sharp` dependency and per-collection Sharp-specific `upload` options (resizeOptions, imageSizes, formatOptions, trimOptions, constructorOptions, withMetadata, crop, focalPoint) into `sharpTransformer({ collections })`, registered under `upload.transformers`, with `imageSizes` renamed to `variants`. Also renames `imageSizes` to `variants` in existing `sharpTransformer({ collections })` entries.'
428
+ };
429
+
430
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/transforms/migrate-sharp-to-transformer/index.ts"],"sourcesContent":["import type {\n ArrayLiteralExpression,\n Expression,\n Identifier,\n Symbol as MorphSymbol,\n ObjectLiteralExpression,\n PropertyAssignment,\n ShorthandPropertyAssignment,\n SourceFile,\n StringLiteral,\n} from 'ts-morph'\n\nimport { Node, SyntaxKind } from 'ts-morph'\n\nimport type { Transform } from '../../types.js'\n\nconst TRANSFORMER_MODULE = '@payloadcms/transformer-sharp'\nconst TRANSFORMER_NAME = 'sharpTransformer'\nconst VARIANTS_KEY = 'variants'\n\nconst IDENTIFIER_PATTERN = /^[A-Z_$][\\w$]*$/i\n/** Whether `value` can be used as a plain (unquoted, non-bracketed) object literal key. */\nfunction isSafePlainObjectKey(value: string): boolean {\n return IDENTIFIER_PATTERN.test(value)\n}\n\n/** Fields moved from a collection's `upload` object into `sharpTransformer({ collections })`. */\nconst MOVED_UPLOAD_FIELDS = [\n 'constructorOptions',\n 'formatOptions',\n 'resizeOptions',\n 'trimOptions',\n 'withMetadata',\n 'imageSizes',\n 'crop',\n 'focalPoint',\n]\n\nconst findBuildConfigLocalNames = (file: SourceFile): Set<string> => {\n const localNames = new Set<string>()\n\n for (const importDecl of file.getImportDeclarations()) {\n if (importDecl.getModuleSpecifierValue() !== 'payload') {\n continue\n }\n for (const spec of importDecl.getNamedImports()) {\n if (spec.getName() === 'buildConfig') {\n localNames.add(spec.getAliasNode()?.getText() ?? spec.getName())\n }\n }\n }\n\n return localNames\n}\n\ntype SharpTransformerBinding = {\n /** Whether `localName` is a value import of `sharpTransformer` from `@payloadcms/transformer-sharp`. */\n isImported: boolean\n /** The identifier `sharpTransformer` is (or will be) called through in this file. */\n localName: string\n}\n\n/**\n * Resolves the local binding of the imported `sharpTransformer`, honoring an alias such as\n * `import { sharpTransformer as st }`. When it isn't imported yet, picks a name no other\n * identifier in the file uses, so a local `sharpTransformer` function is never mistaken for it.\n */\nfunction resolveSharpTransformerBinding(sourceFile: SourceFile): SharpTransformerBinding {\n const namedImports = sourceFile\n .getImportDeclarations()\n .filter((decl) => decl.getModuleSpecifierValue() === TRANSFORMER_MODULE && !decl.isTypeOnly())\n .flatMap((decl) => decl.getNamedImports())\n .filter((named) => named.getName() === TRANSFORMER_NAME && !named.isTypeOnly())\n\n const unaliasedImport = namedImports.find((named) => !named.getAliasNode())\n const aliasedImport = namedImports.find((named) => named.getAliasNode())\n\n if (unaliasedImport) {\n return { isImported: true, localName: TRANSFORMER_NAME }\n }\n\n if (aliasedImport) {\n return { isImported: true, localName: aliasedImport.getAliasNode()!.getText() }\n }\n\n const usedIdentifiers = new Set(\n sourceFile\n .getDescendantsOfKind(SyntaxKind.Identifier)\n .map((identifier) => identifier.getText()),\n )\n\n let localName = TRANSFORMER_NAME\n for (let suffix = 2; usedIdentifiers.has(localName); suffix++) {\n localName = `${TRANSFORMER_NAME}${suffix}`\n }\n\n return { isImported: false, localName }\n}\n\nfunction ensureSharpTransformerImport({\n localName,\n sourceFile,\n}: {\n localName: string\n sourceFile: SourceFile\n}): void {\n const namedImport =\n localName === TRANSFORMER_NAME ? TRANSFORMER_NAME : { name: TRANSFORMER_NAME, alias: localName }\n\n const existing = sourceFile\n .getImportDeclarations()\n .find((decl) => decl.getModuleSpecifierValue() === TRANSFORMER_MODULE && !decl.isTypeOnly())\n\n if (!existing) {\n const otherImports = sourceFile.getImportDeclarations()\n const fileOmitsSemicolonsOnImports =\n otherImports.length > 0 && otherImports.every((decl) => !decl.getText().endsWith(';'))\n\n const insertedImport = sourceFile.addImportDeclaration({\n moduleSpecifier: TRANSFORMER_MODULE,\n namedImports: [namedImport],\n })\n\n // ts-morph always appends a semicolon; strip it when the file's other imports don't use them.\n if (fileOmitsSemicolonsOnImports) {\n const insertedImportText = insertedImport.getText()\n if (insertedImportText.endsWith(';')) {\n insertedImport.replaceWithText(insertedImportText.slice(0, -1))\n }\n }\n\n return\n }\n\n const alreadyImported = existing\n .getNamedImports()\n .some(\n (named) =>\n named.getName() === TRANSFORMER_NAME &&\n !named.isTypeOnly() &&\n (named.getAliasNode()?.getText() ?? TRANSFORMER_NAME) === localName,\n )\n\n if (!alreadyImported) {\n existing.addNamedImport(namedImport)\n }\n}\n\ntype CollectionSharpEntry = {\n /** `<slug>: { ... }` text for the `sharpTransformer({ collections })` map. */\n entryText: string\n /** Moved properties, removed from the collection only once `sharpTransformer` is registered. */\n movedProps: (PropertyAssignment | ShorthandPropertyAssignment)[]\n uploadObj: ObjectLiteralExpression\n}\n\n/**\n * Reads Sharp-owned fields off one collection's `upload` object literal into\n * a `<slug>: { ... }` entry text for the `sharpTransformer({ collections })` map,\n * without modifying the collection. Returns `undefined` when the collection has nothing to migrate.\n */\nfunction extractCollectionSharpEntry({\n collectionObj,\n configFile,\n notes,\n}: {\n collectionObj: ObjectLiteralExpression\n /** The file the `sharpTransformer` call is written to; a collection declared elsewhere is moved across files. */\n configFile: SourceFile\n notes: string[]\n}): CollectionSharpEntry | undefined {\n const filePath = collectionObj.getSourceFile().getFilePath()\n const isExternal = collectionObj.getSourceFile() !== configFile\n const slugProp = collectionObj.getProperty('slug')\n const slugAssignment = slugProp?.asKind(SyntaxKind.PropertyAssignment)\n const slugInitializer = slugAssignment?.getInitializer()\n\n if (!slugInitializer) {\n return undefined\n }\n\n const uploadProp = collectionObj.getProperty('upload')\n if (!uploadProp || !Node.isPropertyAssignment(uploadProp)) {\n return undefined\n }\n\n const uploadObj = uploadProp.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression)\n if (!uploadObj) {\n if (uploadProp.getInitializer()?.getKind() !== SyntaxKind.TrueKeyword) {\n notes.push(\n `${filePath}: collection ${slugInitializer.getText()}'s \\`upload\\` option is not an inline object — check it for Sharp-specific fields (resizeOptions/imageSizes/formatOptions/trimOptions/constructorOptions/withMetadata/crop/focalPoint) manually.`,\n )\n }\n return undefined\n }\n\n const uploadHasSpread = uploadObj.getProperties().some((prop) => Node.isSpreadAssignment(prop))\n if (uploadHasSpread) {\n notes.push(\n `${filePath}: collection ${slugInitializer.getText()}'s \\`upload\\` object contains a spread — Sharp-specific fields (resizeOptions/imageSizes/formatOptions/trimOptions/constructorOptions/withMetadata/crop/focalPoint) hidden inside it need manual review.`,\n )\n }\n\n const movedTexts: string[] = []\n const movedProps: CollectionSharpEntry['movedProps'] = []\n for (const name of MOVED_UPLOAD_FIELDS) {\n const prop = uploadObj.getProperty(name)\n if (!prop) {\n continue\n }\n\n // A shorthand `imageSizes` reads the same binding from `buildConfig`'s argument,\n // where the `sharpTransformer` call is inserted, so it moves verbatim.\n if (Node.isPropertyAssignment(prop) || Node.isShorthandPropertyAssignment(prop)) {\n const localReference = isExternal ? findLocalReference({ node: prop }) : undefined\n\n // Moving the text into the config file would leave this reference unresolved there.\n if (localReference) {\n notes.push(\n `${filePath}: collection ${slugInitializer.getText()}'s \\`upload.${name}\\` refers to \\`${localReference.getText()}\\`, which isn't available in ${configFile.getFilePath()} — move this collection's Sharp-specific \\`upload\\` fields into \\`sharpTransformer({ collections })\\` manually.`,\n )\n return undefined\n }\n\n movedTexts.push(name === 'imageSizes' ? printAsVariants(prop) : prop.print())\n movedProps.push(prop)\n continue\n }\n\n notes.push(\n `${filePath}: collection ${slugInitializer.getText()}'s \\`upload.${name}\\` isn't a plain property — move it into \\`sharpTransformer({ collections })\\` manually.`,\n )\n }\n\n if (movedTexts.length === 0) {\n return undefined\n }\n\n const slugLiteralValue = getSlugLiteralValue({ isExternal, slugInitializer })\n\n if (isExternal && slugLiteralValue === undefined) {\n notes.push(\n `${filePath}: collection ${slugInitializer.getText()}'s slug isn't a string constant — move its Sharp-specific \\`upload\\` fields into \\`sharpTransformer({ collections })\\` manually.`,\n )\n return undefined\n }\n\n // A slug constant from another file isn't in scope in the config file, so it's keyed by value.\n const keyText =\n slugLiteralValue !== undefined && isSafePlainObjectKey(slugLiteralValue)\n ? slugLiteralValue\n : isExternal && !isStringLiteralNode(slugInitializer)\n ? `'${slugLiteralValue!.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\")}'`\n : `[${slugInitializer.getText()}]`\n\n return { entryText: `${keyText}: { ${movedTexts.join(', ')} }`, movedProps, uploadObj }\n}\n\nfunction isStringLiteralNode(node: Node): boolean {\n return Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)\n}\n\n/**\n * A slug written as a string literal or, for a collection in another file, a constant whose\n * type is a string literal (e.g. `slug: mediaSlug` with `const mediaSlug = 'media'`).\n */\nfunction getSlugLiteralValue({\n isExternal,\n slugInitializer,\n}: {\n isExternal: boolean\n slugInitializer: Expression\n}): string | undefined {\n if (isStringLiteralNode(slugInitializer)) {\n return (slugInitializer as StringLiteral).getLiteralValue()\n }\n\n if (!isExternal) {\n return undefined\n }\n\n const slugType = slugInitializer.getType()\n\n return slugType.isStringLiteral() ? (slugType.getLiteralValue() as string) : undefined\n}\n\n/**\n * The first identifier inside `node` bound to a declaration elsewhere in the project, such as an\n * import or a local variable. Declarations inside `node` itself (parameters, its own property\n * names) and ambient/library ones (`undefined`, `Math`) don't count.\n */\nfunction findLocalReference({ node }: { node: Node }): Identifier | undefined {\n const sourceFile = node.getSourceFile()\n\n return node.getDescendantsOfKind(SyntaxKind.Identifier).find((identifier) =>\n (identifier.getSymbol()?.getDeclarations() ?? []).some((declaration) => {\n const declarationFile = declaration.getSourceFile()\n\n if (declarationFile.isDeclarationFile() || declarationFile.isFromExternalLibrary()) {\n return false\n }\n\n return (\n declarationFile !== sourceFile ||\n declaration.getPos() < node.getPos() ||\n declaration.getEnd() > node.getEnd()\n )\n }),\n )\n}\n\n/**\n * Follows a `collections` array element written as an identifier (usually an imported\n * collection, e.g. `import { Media } from './collections/Media'`) to the object literal it's\n * declared as, unwrapping `satisfies`/`as`/parentheses. Returns `undefined` for anything else,\n * such as a factory call.\n */\nfunction resolveCollectionObject({\n expression,\n}: {\n expression: Node\n}): ObjectLiteralExpression | undefined {\n let current: Node | undefined = expression\n\n for (let depth = 0; current && depth < 5; depth++) {\n while (\n Node.isSatisfiesExpression(current) ||\n Node.isAsExpression(current) ||\n Node.isParenthesizedExpression(current)\n ) {\n current = current.getExpression()\n }\n\n if (Node.isObjectLiteralExpression(current)) {\n return current\n }\n\n if (!Node.isIdentifier(current)) {\n return undefined\n }\n\n const symbol: MorphSymbol | undefined = current.getSymbol()\n const declaration: Node | undefined = (\n symbol?.isAlias() ? symbol.getAliasedSymbol() : symbol\n )?.getDeclarations()[0]\n\n if (Node.isVariableDeclaration(declaration)) {\n current = declaration.getInitializer()\n } else if (Node.isExportAssignment(declaration)) {\n current = declaration.getExpression()\n } else {\n return undefined\n }\n }\n\n return undefined\n}\n\nfunction removeMovedCollectionProps({ movedProps, uploadObj }: CollectionSharpEntry): void {\n for (const prop of movedProps) {\n prop.remove()\n }\n\n // Avoid leaving `upload: {\\n}` spread across two lines once every property moves out.\n if (uploadObj.getProperties().length === 0) {\n uploadObj.replaceWithText('{}')\n }\n}\n\n/**\n * Builds every `<slug>: { ... }` entry for a `buildConfig({ collections })` array,\n * skipping (and, for a present `sharp` signal, noting) entries that aren't inline\n * object literals or whose `collections` array isn't statically analyzable.\n */\nfunction extractSharpCollectionEntries({\n configObj,\n notes,\n}: {\n configObj: ObjectLiteralExpression\n notes: string[]\n}): CollectionSharpEntry[] {\n const configFile = configObj.getSourceFile()\n const filePath = configFile.getFilePath()\n const collectionsProp = configObj.getProperty('collections')\n if (!collectionsProp || !Node.isPropertyAssignment(collectionsProp)) {\n return []\n }\n\n const arrayLiteral = collectionsProp.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression)\n if (!arrayLiteral) {\n notes.push(\n `${filePath}: \\`collections\\` isn't an inline array — check each collection for Sharp-specific \\`upload\\` fields (resizeOptions/imageSizes/formatOptions/trimOptions/constructorOptions/withMetadata/crop/focalPoint) and move them into \\`sharpTransformer({ collections })\\` manually.`,\n )\n return []\n }\n\n const entries: CollectionSharpEntry[] = []\n\n for (const el of arrayLiteral.getElements()) {\n const collectionObj = resolveCollectionObject({ expression: el })\n\n if (!collectionObj) {\n notes.push(\n `${filePath}: a collection in \\`collections\\` (\\`${el.getText()}\\`) is defined externally — check it for Sharp-specific \\`upload\\` fields and move them into \\`sharpTransformer({ collections })\\` manually.`,\n )\n continue\n }\n\n const entry = extractCollectionSharpEntry({ collectionObj, configFile, notes })\n if (entry) {\n entries.push(entry)\n }\n }\n\n return entries\n}\n\n/** `sharpTransformer` authors image sizes as `variants`; the collection's `imageSizes` is renamed on the way in. */\nfunction printAsVariants(prop: PropertyAssignment | ShorthandPropertyAssignment): string {\n return Node.isShorthandPropertyAssignment(prop)\n ? `${VARIANTS_KEY}: ${prop.getName()}`\n : `${VARIANTS_KEY}: ${prop.getInitializerOrThrow().print()}`\n}\n\n/**\n * Renames `imageSizes` to `variants` inside every inline `sharpTransformer({ collections })`\n * entry in the file — configs migrated before `variants` existed. Returns whether it changed\n * anything.\n */\nfunction renameImageSizesInSharpTransformerCalls({\n notes,\n sourceFile,\n transformerLocalName,\n}: {\n notes: string[]\n sourceFile: SourceFile\n transformerLocalName: string\n}): boolean {\n let hasChanged = false\n\n const sharpTransformerCalls = sourceFile\n .getDescendantsOfKind(SyntaxKind.CallExpression)\n .filter((call) => {\n const callee = call.getExpression()\n return Node.isIdentifier(callee) && callee.getText() === transformerLocalName\n })\n\n for (const call of sharpTransformerCalls) {\n const collectionsObj = call\n .getArguments()[0]\n ?.asKind(SyntaxKind.ObjectLiteralExpression)\n ?.getProperty('collections')\n ?.asKind(SyntaxKind.PropertyAssignment)\n ?.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression)\n\n for (const entry of collectionsObj?.getProperties() ?? []) {\n const entryObj = Node.isPropertyAssignment(entry)\n ? entry.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression)\n : undefined\n\n if (!entryObj) {\n notes.push(\n `${sourceFile.getFilePath()}: a \\`${TRANSFORMER_NAME}({ collections })\\` entry isn't an inline object — rename any \\`imageSizes\\` in it to \\`${VARIANTS_KEY}\\` manually.`,\n )\n continue\n }\n\n const imageSizesProp = entryObj.getProperty('imageSizes')\n\n if (imageSizesProp && Node.isPropertyAssignment(imageSizesProp)) {\n imageSizesProp.getNameNode().replaceWithText(VARIANTS_KEY)\n hasChanged = true\n } else if (imageSizesProp && Node.isShorthandPropertyAssignment(imageSizesProp)) {\n imageSizesProp.replaceWithText(printAsVariants(imageSizesProp))\n hasChanged = true\n }\n }\n }\n\n return hasChanged\n}\n\nfunction findSharpTransformerCall({\n transformerLocalName,\n transformersArray,\n}: {\n transformerLocalName: string\n transformersArray: ArrayLiteralExpression\n}) {\n return transformersArray.getElements().find((el) => {\n if (!Node.isCallExpression(el)) {\n return false\n }\n const callee = el.getExpression()\n return Node.isIdentifier(callee) && callee.getText() === transformerLocalName\n })\n}\n\nexport const migrateSharpToTransformer: Transform = {\n name: 'migrate-sharp-to-transformer',\n apply: ({ project }) => {\n const filesChanged = new Set<string>()\n const notes: string[] = []\n\n for (const sourceFile of project.getSourceFiles()) {\n const { isImported, localName: transformerLocalName } =\n resolveSharpTransformerBinding(sourceFile)\n\n if (\n isImported &&\n renameImageSizesInSharpTransformerCalls({ notes, sourceFile, transformerLocalName })\n ) {\n filesChanged.add(sourceFile.getFilePath())\n }\n\n const buildConfigLocalNames = findBuildConfigLocalNames(sourceFile)\n if (buildConfigLocalNames.size === 0) {\n continue\n }\n\n const calls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).filter((call) => {\n const expr = call.getExpression()\n return Node.isIdentifier(expr) && buildConfigLocalNames.has(expr.getText())\n })\n\n for (const call of calls) {\n const [arg] = call.getArguments()\n const configObj = arg?.asKind(SyntaxKind.ObjectLiteralExpression)\n if (!configObj) {\n notes.push(\n `${sourceFile.getFilePath()}: \\`buildConfig\\` argument is not an inline object literal — check it manually for a top-level \\`sharp\\` dependency and per-collection Sharp-specific \\`upload\\` options.`,\n )\n continue\n }\n\n const uploadProp = configObj.getProperty('upload')\n const uploadObj = uploadProp\n ?.asKind(SyntaxKind.PropertyAssignment)\n ?.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression)\n const existingTransformersProp = uploadObj?.getProperty('transformers')\n const existingTransformersArray = existingTransformersProp\n ?.asKind(SyntaxKind.PropertyAssignment)\n ?.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression)\n\n if (\n existingTransformersArray &&\n findSharpTransformerCall({\n transformerLocalName,\n transformersArray: existingTransformersArray,\n })\n ) {\n // Already migrated, but a leftover `sharp` property would fail a later\n // type-check with no signal from this codemod — flag it here.\n if (configObj.getProperty('sharp')) {\n notes.push(\n `${sourceFile.getFilePath()}: a top-level \\`sharp\\` property remains even though \\`sharpTransformer\\` is already registered — move any value you still need into the existing \\`sharpTransformer\\` call, then remove \\`sharp\\` manually.`,\n )\n }\n continue\n }\n\n const sharpProp = configObj.getProperty('sharp')\n let sharpExpressionText: string | undefined\n if (sharpProp && Node.isPropertyAssignment(sharpProp)) {\n sharpExpressionText = sharpProp.getInitializer()?.getText()\n } else if (sharpProp && Node.isShorthandPropertyAssignment(sharpProp)) {\n sharpExpressionText = sharpProp.getName()\n }\n\n const collectionEntries = extractSharpCollectionEntries({ configObj, notes })\n\n if (!sharpExpressionText && collectionEntries.length === 0) {\n continue\n }\n\n const transformerArgs: string[] = []\n if (sharpExpressionText) {\n transformerArgs.push(\n sharpExpressionText === 'sharp' ? 'sharp' : `sharp: ${sharpExpressionText}`,\n )\n }\n if (collectionEntries.length > 0) {\n transformerArgs.push(\n `collections: { ${collectionEntries.map((entry) => entry.entryText).join(', ')} }`,\n )\n }\n\n const transformerCallText = `${transformerLocalName}({ ${transformerArgs.join(', ')} })`\n\n // Adding a `transformers` property next to a non-array one, or after a spread\n // that may already set it, would create a duplicate key whose last value wins\n // at runtime — silently dropping the existing transformers.\n const uploadHasSpread = uploadObj\n ?.getProperties()\n .some((prop) => Node.isSpreadAssignment(prop))\n\n // The old settings are only removed once the replacement call is registered —\n // otherwise the migrated config would silently lose its image processing.\n let isRegistered = true\n\n if (existingTransformersArray) {\n existingTransformersArray.addElement(transformerCallText)\n } else if (existingTransformersProp) {\n isRegistered = false\n notes.push(\n `${sourceFile.getFilePath()}: \\`upload.transformers\\` isn't an inline array — add \\`${transformerCallText}\\` to it manually, then remove the migrated Sharp settings.`,\n )\n } else if (uploadHasSpread) {\n isRegistered = false\n notes.push(\n `${sourceFile.getFilePath()}: \\`upload\\` contains a spread that may already set \\`transformers\\` — add \\`${transformerCallText}\\` to its transformers manually, then remove the migrated Sharp settings.`,\n )\n } else if (uploadObj) {\n uploadObj.addPropertyAssignment({\n name: 'transformers',\n initializer: `[${transformerCallText}]`,\n })\n } else if (uploadProp) {\n isRegistered = false\n notes.push(\n `${sourceFile.getFilePath()}: \\`upload\\` isn't an inline object — add \\`transformers: [${transformerCallText}]\\` to it manually, then remove the migrated Sharp settings.`,\n )\n } else {\n configObj.addPropertyAssignment({\n name: 'upload',\n initializer: `{ transformers: [${transformerCallText}] }`,\n })\n }\n\n if (!isRegistered) {\n continue\n }\n\n sharpProp?.remove()\n for (const entry of collectionEntries) {\n removeMovedCollectionProps(entry)\n filesChanged.add(entry.uploadObj.getSourceFile().getFilePath())\n }\n\n ensureSharpTransformerImport({ localName: transformerLocalName, sourceFile })\n filesChanged.add(sourceFile.getFilePath())\n }\n }\n\n if (filesChanged.size > 0) {\n notes.push(\n `Install the new dependency this migration relies on: pnpm add @payloadcms/transformer-sharp`,\n )\n }\n\n return { filesChanged: Array.from(filesChanged), notes: notes.length ? notes : undefined }\n },\n description:\n 'Move a top-level `sharp` dependency and per-collection Sharp-specific `upload` options (resizeOptions, imageSizes, formatOptions, trimOptions, constructorOptions, withMetadata, crop, focalPoint) into `sharpTransformer({ collections })`, registered under `upload.transformers`, with `imageSizes` renamed to `variants`. Also renames `imageSizes` to `variants` in existing `sharpTransformer({ collections })` entries.',\n}\n"],"names":["Node","SyntaxKind","TRANSFORMER_MODULE","TRANSFORMER_NAME","VARIANTS_KEY","IDENTIFIER_PATTERN","isSafePlainObjectKey","value","test","MOVED_UPLOAD_FIELDS","findBuildConfigLocalNames","file","localNames","Set","importDecl","getImportDeclarations","getModuleSpecifierValue","spec","getNamedImports","getName","add","getAliasNode","getText","resolveSharpTransformerBinding","sourceFile","namedImports","filter","decl","isTypeOnly","flatMap","named","unaliasedImport","find","aliasedImport","isImported","localName","usedIdentifiers","getDescendantsOfKind","Identifier","map","identifier","suffix","has","ensureSharpTransformerImport","namedImport","name","alias","existing","otherImports","fileOmitsSemicolonsOnImports","length","every","endsWith","insertedImport","addImportDeclaration","moduleSpecifier","insertedImportText","replaceWithText","slice","alreadyImported","some","addNamedImport","extractCollectionSharpEntry","collectionObj","configFile","notes","filePath","getSourceFile","getFilePath","isExternal","slugProp","getProperty","slugAssignment","asKind","PropertyAssignment","slugInitializer","getInitializer","undefined","uploadProp","isPropertyAssignment","uploadObj","getInitializerIfKind","ObjectLiteralExpression","getKind","TrueKeyword","push","uploadHasSpread","getProperties","prop","isSpreadAssignment","movedTexts","movedProps","isShorthandPropertyAssignment","localReference","findLocalReference","node","printAsVariants","print","slugLiteralValue","getSlugLiteralValue","keyText","isStringLiteralNode","replace","entryText","join","isStringLiteral","isNoSubstitutionTemplateLiteral","getLiteralValue","slugType","getType","getSymbol","getDeclarations","declaration","declarationFile","isDeclarationFile","isFromExternalLibrary","getPos","getEnd","resolveCollectionObject","expression","current","depth","isSatisfiesExpression","isAsExpression","isParenthesizedExpression","getExpression","isObjectLiteralExpression","isIdentifier","symbol","isAlias","getAliasedSymbol","isVariableDeclaration","isExportAssignment","removeMovedCollectionProps","remove","extractSharpCollectionEntries","configObj","collectionsProp","arrayLiteral","ArrayLiteralExpression","entries","el","getElements","entry","getInitializerOrThrow","renameImageSizesInSharpTransformerCalls","transformerLocalName","hasChanged","sharpTransformerCalls","CallExpression","call","callee","collectionsObj","getArguments","entryObj","imageSizesProp","getNameNode","findSharpTransformerCall","transformersArray","isCallExpression","migrateSharpToTransformer","apply","project","filesChanged","getSourceFiles","buildConfigLocalNames","size","calls","expr","arg","existingTransformersProp","existingTransformersArray","sharpProp","sharpExpressionText","collectionEntries","transformerArgs","transformerCallText","isRegistered","addElement","addPropertyAssignment","initializer","Array","from","description"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { buildConfig } from 'payload';
2
+ export default buildConfig({
3
+ collections: [
4
+ {
5
+ slug: 'posts',
6
+ fields: []
7
+ }
8
+ ]
9
+ });
10
+
11
+ //# sourceMappingURL=no-match.input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/transforms/migrate-sharp-to-transformer/no-match.input.ts"],"sourcesContent":["import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: [\n {\n slug: 'posts',\n fields: [],\n },\n ],\n})\n"],"names":["buildConfig","collections","slug","fields"],"mappings":"AAAA,SAASA,WAAW,QAAQ,UAAS;AAErC,eAAeA,YAAY;IACzBC,aAAa;QACX;YACEC,MAAM;YACNC,QAAQ,EAAE;QACZ;KACD;AACH,GAAE"}
@@ -0,0 +1,11 @@
1
+ import { buildConfig } from 'payload';
2
+ export default buildConfig({
3
+ collections: [
4
+ {
5
+ slug: 'posts',
6
+ fields: []
7
+ }
8
+ ]
9
+ });
10
+
11
+ //# sourceMappingURL=no-match.output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/transforms/migrate-sharp-to-transformer/no-match.output.ts"],"sourcesContent":["import { buildConfig } from 'payload'\n\nexport default buildConfig({\n collections: [\n {\n slug: 'posts',\n fields: [],\n },\n ],\n})\n"],"names":["buildConfig","collections","slug","fields"],"mappings":"AAAA,SAASA,WAAW,QAAQ,UAAS;AAErC,eAAeA,YAAY;IACzBC,aAAa;QACX;YACEC,MAAM;YACNC,QAAQ,EAAE;QACZ;KACD;AACH,GAAE"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transforms/remove-storage-always-insert-fields/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAW/C,eAAO,MAAM,+BAA+B,EAAE,SA2D7C,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transforms/remove-storage-always-insert-fields/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAW/C,eAAO,MAAM,+BAA+B,EAAE,SAgE7C,CAAA"}
@@ -40,6 +40,10 @@ export const removeStorageAlwaysInsertFields = {
40
40
  continue;
41
41
  }
42
42
  const localStorageFactoryName = storageFactoryImport.getAliasNode() ?? storageFactoryImport.getNameNode();
43
+ // Always an Identifier in valid code: a string-literal import name requires an alias.
44
+ if (!Node.isIdentifier(localStorageFactoryName)) {
45
+ continue;
46
+ }
43
47
  for (const reference of localStorageFactoryName.findReferencesAsNodes()){
44
48
  const call = reference.getParentIfKind(SyntaxKind.CallExpression);
45
49
  if (!call || call.getExpression() !== reference) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/transforms/remove-storage-always-insert-fields/index.ts"],"sourcesContent":["import { Node, SyntaxKind } from 'ts-morph'\n\nimport type { Transform } from '../../types.js'\n\nconst storageFactoryByPackage = new Map([\n ['@payloadcms/plugin-cloud-storage', 'cloudStoragePlugin'],\n ['@payloadcms/storage-azure', 'azureStorage'],\n ['@payloadcms/storage-gcs', 'gcsStorage'],\n ['@payloadcms/storage-r2', 'r2Storage'],\n ['@payloadcms/storage-s3', 's3Storage'],\n ['@payloadcms/storage-vercel-blob', 'vercelBlobStorage'],\n])\n\nexport const removeStorageAlwaysInsertFields: Transform = {\n name: 'remove-storage-always-insert-fields',\n apply: ({ project }) => {\n const filesChanged = new Set<string>()\n\n for (const sourceFile of project.getSourceFiles()) {\n for (const importDeclaration of sourceFile.getImportDeclarations()) {\n const storageFactoryName = storageFactoryByPackage.get(\n importDeclaration.getModuleSpecifierValue(),\n )\n\n if (!storageFactoryName) {\n continue\n }\n\n const storageFactoryImport = importDeclaration\n .getNamedImports()\n .find((namedImport) => namedImport.getName() === storageFactoryName)\n\n if (!storageFactoryImport) {\n continue\n }\n\n const localStorageFactoryName =\n storageFactoryImport.getAliasNode() ?? storageFactoryImport.getNameNode()\n\n for (const reference of localStorageFactoryName.findReferencesAsNodes()) {\n const call = reference.getParentIfKind(SyntaxKind.CallExpression)\n\n if (!call || call.getExpression() !== reference) {\n continue\n }\n\n const [options] = call.getArguments()\n\n if (!options || !Node.isObjectLiteralExpression(options)) {\n continue\n }\n\n if (options.getProperties().some((property) => Node.isSpreadAssignment(property))) {\n continue\n }\n\n const alwaysInsertFieldsProperty = options.getProperty('alwaysInsertFields')\n\n if (!alwaysInsertFieldsProperty) {\n continue\n }\n\n alwaysInsertFieldsProperty.remove()\n filesChanged.add(sourceFile.getFilePath())\n }\n }\n }\n\n return { filesChanged: Array.from(filesChanged) }\n },\n description:\n 'Remove the obsolete `alwaysInsertFields` option from cloud storage plugin and storage adapter configs. The prefix field is now always inserted.',\n}\n"],"names":["Node","SyntaxKind","storageFactoryByPackage","Map","removeStorageAlwaysInsertFields","name","apply","project","filesChanged","Set","sourceFile","getSourceFiles","importDeclaration","getImportDeclarations","storageFactoryName","get","getModuleSpecifierValue","storageFactoryImport","getNamedImports","find","namedImport","getName","localStorageFactoryName","getAliasNode","getNameNode","reference","findReferencesAsNodes","call","getParentIfKind","CallExpression","getExpression","options","getArguments","isObjectLiteralExpression","getProperties","some","property","isSpreadAssignment","alwaysInsertFieldsProperty","getProperty","remove","add","getFilePath","Array","from","description"],"mappings":"AAAA,SAASA,IAAI,EAAEC,UAAU,QAAQ,WAAU;AAI3C,MAAMC,0BAA0B,IAAIC,IAAI;IACtC;QAAC;QAAoC;KAAqB;IAC1D;QAAC;QAA6B;KAAe;IAC7C;QAAC;QAA2B;KAAa;IACzC;QAAC;QAA0B;KAAY;IACvC;QAAC;QAA0B;KAAY;IACvC;QAAC;QAAmC;KAAoB;CACzD;AAED,OAAO,MAAMC,kCAA6C;IACxDC,MAAM;IACNC,OAAO,CAAC,EAAEC,OAAO,EAAE;QACjB,MAAMC,eAAe,IAAIC;QAEzB,KAAK,MAAMC,cAAcH,QAAQI,cAAc,GAAI;YACjD,KAAK,MAAMC,qBAAqBF,WAAWG,qBAAqB,GAAI;gBAClE,MAAMC,qBAAqBZ,wBAAwBa,GAAG,CACpDH,kBAAkBI,uBAAuB;gBAG3C,IAAI,CAACF,oBAAoB;oBACvB;gBACF;gBAEA,MAAMG,uBAAuBL,kBAC1BM,eAAe,GACfC,IAAI,CAAC,CAACC,cAAgBA,YAAYC,OAAO,OAAOP;gBAEnD,IAAI,CAACG,sBAAsB;oBACzB;gBACF;gBAEA,MAAMK,0BACJL,qBAAqBM,YAAY,MAAMN,qBAAqBO,WAAW;gBAEzE,KAAK,MAAMC,aAAaH,wBAAwBI,qBAAqB,GAAI;oBACvE,MAAMC,OAAOF,UAAUG,eAAe,CAAC3B,WAAW4B,cAAc;oBAEhE,IAAI,CAACF,QAAQA,KAAKG,aAAa,OAAOL,WAAW;wBAC/C;oBACF;oBAEA,MAAM,CAACM,QAAQ,GAAGJ,KAAKK,YAAY;oBAEnC,IAAI,CAACD,WAAW,CAAC/B,KAAKiC,yBAAyB,CAACF,UAAU;wBACxD;oBACF;oBAEA,IAAIA,QAAQG,aAAa,GAAGC,IAAI,CAAC,CAACC,WAAapC,KAAKqC,kBAAkB,CAACD,YAAY;wBACjF;oBACF;oBAEA,MAAME,6BAA6BP,QAAQQ,WAAW,CAAC;oBAEvD,IAAI,CAACD,4BAA4B;wBAC/B;oBACF;oBAEAA,2BAA2BE,MAAM;oBACjChC,aAAaiC,GAAG,CAAC/B,WAAWgC,WAAW;gBACzC;YACF;QACF;QAEA,OAAO;YAAElC,cAAcmC,MAAMC,IAAI,CAACpC;QAAc;IAClD;IACAqC,aACE;AACJ,EAAC"}
1
+ {"version":3,"sources":["../../../src/transforms/remove-storage-always-insert-fields/index.ts"],"sourcesContent":["import { Node, SyntaxKind } from 'ts-morph'\n\nimport type { Transform } from '../../types.js'\n\nconst storageFactoryByPackage = new Map([\n ['@payloadcms/plugin-cloud-storage', 'cloudStoragePlugin'],\n ['@payloadcms/storage-azure', 'azureStorage'],\n ['@payloadcms/storage-gcs', 'gcsStorage'],\n ['@payloadcms/storage-r2', 'r2Storage'],\n ['@payloadcms/storage-s3', 's3Storage'],\n ['@payloadcms/storage-vercel-blob', 'vercelBlobStorage'],\n])\n\nexport const removeStorageAlwaysInsertFields: Transform = {\n name: 'remove-storage-always-insert-fields',\n apply: ({ project }) => {\n const filesChanged = new Set<string>()\n\n for (const sourceFile of project.getSourceFiles()) {\n for (const importDeclaration of sourceFile.getImportDeclarations()) {\n const storageFactoryName = storageFactoryByPackage.get(\n importDeclaration.getModuleSpecifierValue(),\n )\n\n if (!storageFactoryName) {\n continue\n }\n\n const storageFactoryImport = importDeclaration\n .getNamedImports()\n .find((namedImport) => namedImport.getName() === storageFactoryName)\n\n if (!storageFactoryImport) {\n continue\n }\n\n const localStorageFactoryName =\n storageFactoryImport.getAliasNode() ?? storageFactoryImport.getNameNode()\n\n // Always an Identifier in valid code: a string-literal import name requires an alias.\n if (!Node.isIdentifier(localStorageFactoryName)) {\n continue\n }\n\n for (const reference of localStorageFactoryName.findReferencesAsNodes()) {\n const call = reference.getParentIfKind(SyntaxKind.CallExpression)\n\n if (!call || call.getExpression() !== reference) {\n continue\n }\n\n const [options] = call.getArguments()\n\n if (!options || !Node.isObjectLiteralExpression(options)) {\n continue\n }\n\n if (options.getProperties().some((property) => Node.isSpreadAssignment(property))) {\n continue\n }\n\n const alwaysInsertFieldsProperty = options.getProperty('alwaysInsertFields')\n\n if (!alwaysInsertFieldsProperty) {\n continue\n }\n\n alwaysInsertFieldsProperty.remove()\n filesChanged.add(sourceFile.getFilePath())\n }\n }\n }\n\n return { filesChanged: Array.from(filesChanged) }\n },\n description:\n 'Remove the obsolete `alwaysInsertFields` option from cloud storage plugin and storage adapter configs. The prefix field is now always inserted.',\n}\n"],"names":["Node","SyntaxKind","storageFactoryByPackage","Map","removeStorageAlwaysInsertFields","name","apply","project","filesChanged","Set","sourceFile","getSourceFiles","importDeclaration","getImportDeclarations","storageFactoryName","get","getModuleSpecifierValue","storageFactoryImport","getNamedImports","find","namedImport","getName","localStorageFactoryName","getAliasNode","getNameNode","isIdentifier","reference","findReferencesAsNodes","call","getParentIfKind","CallExpression","getExpression","options","getArguments","isObjectLiteralExpression","getProperties","some","property","isSpreadAssignment","alwaysInsertFieldsProperty","getProperty","remove","add","getFilePath","Array","from","description"],"mappings":"AAAA,SAASA,IAAI,EAAEC,UAAU,QAAQ,WAAU;AAI3C,MAAMC,0BAA0B,IAAIC,IAAI;IACtC;QAAC;QAAoC;KAAqB;IAC1D;QAAC;QAA6B;KAAe;IAC7C;QAAC;QAA2B;KAAa;IACzC;QAAC;QAA0B;KAAY;IACvC;QAAC;QAA0B;KAAY;IACvC;QAAC;QAAmC;KAAoB;CACzD;AAED,OAAO,MAAMC,kCAA6C;IACxDC,MAAM;IACNC,OAAO,CAAC,EAAEC,OAAO,EAAE;QACjB,MAAMC,eAAe,IAAIC;QAEzB,KAAK,MAAMC,cAAcH,QAAQI,cAAc,GAAI;YACjD,KAAK,MAAMC,qBAAqBF,WAAWG,qBAAqB,GAAI;gBAClE,MAAMC,qBAAqBZ,wBAAwBa,GAAG,CACpDH,kBAAkBI,uBAAuB;gBAG3C,IAAI,CAACF,oBAAoB;oBACvB;gBACF;gBAEA,MAAMG,uBAAuBL,kBAC1BM,eAAe,GACfC,IAAI,CAAC,CAACC,cAAgBA,YAAYC,OAAO,OAAOP;gBAEnD,IAAI,CAACG,sBAAsB;oBACzB;gBACF;gBAEA,MAAMK,0BACJL,qBAAqBM,YAAY,MAAMN,qBAAqBO,WAAW;gBAEzE,sFAAsF;gBACtF,IAAI,CAACxB,KAAKyB,YAAY,CAACH,0BAA0B;oBAC/C;gBACF;gBAEA,KAAK,MAAMI,aAAaJ,wBAAwBK,qBAAqB,GAAI;oBACvE,MAAMC,OAAOF,UAAUG,eAAe,CAAC5B,WAAW6B,cAAc;oBAEhE,IAAI,CAACF,QAAQA,KAAKG,aAAa,OAAOL,WAAW;wBAC/C;oBACF;oBAEA,MAAM,CAACM,QAAQ,GAAGJ,KAAKK,YAAY;oBAEnC,IAAI,CAACD,WAAW,CAAChC,KAAKkC,yBAAyB,CAACF,UAAU;wBACxD;oBACF;oBAEA,IAAIA,QAAQG,aAAa,GAAGC,IAAI,CAAC,CAACC,WAAarC,KAAKsC,kBAAkB,CAACD,YAAY;wBACjF;oBACF;oBAEA,MAAME,6BAA6BP,QAAQQ,WAAW,CAAC;oBAEvD,IAAI,CAACD,4BAA4B;wBAC/B;oBACF;oBAEAA,2BAA2BE,MAAM;oBACjCjC,aAAakC,GAAG,CAAChC,WAAWiC,WAAW;gBACzC;YACF;QACF;QAEA,OAAO;YAAEnC,cAAcoC,MAAMC,IAAI,CAACrC;QAAc;IAClD;IACAsC,aACE;AACJ,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transforms/rename-experimental-table-feature/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAM/C,eAAO,MAAM,8BAA8B,EAAE,SA2C5C,CAAA"}
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().rename(NEW_NAME);
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
  }