( modulePath: string, attributes: ImportAttributes, referencingIdentifier: string, )
| 185 | } |
| 186 | |
| 187 | export function validateImportAttributes( |
| 188 | modulePath: string, |
| 189 | attributes: ImportAttributes, |
| 190 | referencingIdentifier: string, |
| 191 | ): void { |
| 192 | for (const key of Object.keys(attributes)) { |
| 193 | if (key !== 'type') { |
| 194 | throw makeImportAttributeError( |
| 195 | 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED', |
| 196 | `Import attribute "${key}" with value "${attributes[key]}" is not supported (importing "${modulePath}" from ${referencingIdentifier})`, |
| 197 | ); |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | const declaredType = attributes.type; |
| 202 | const isJson = isJsonModule(modulePath); |
| 203 | |
| 204 | if (isJson) { |
| 205 | if (declaredType === undefined) { |
| 206 | // TODO(jest next major): match Node and throw |
| 207 | // ERR_IMPORT_ATTRIBUTE_MISSING here. Until then, warn so existing users |
| 208 | // without `with { type: 'json' }` keep working. |
| 209 | const dedupeKey = `${referencingIdentifier}::${modulePath}`; |
| 210 | if (!warnedMissingJsonAttributePairs.has(dedupeKey)) { |
| 211 | if (warnedMissingJsonAttributePairs.size >= MAX_WARNED_PAIRS) { |
| 212 | warnedMissingJsonAttributePairs.clear(); |
| 213 | } |
| 214 | warnedMissingJsonAttributePairs.add(dedupeKey); |
| 215 | const moduleLabel = describeForWarning(modulePath); |
| 216 | console.warn( |
| 217 | 'Jest: importing JSON without an import attribute is deprecated and will be a hard error in the next major. ' + |
| 218 | `Update the import of "${moduleLabel}" (from ${referencingIdentifier}): ` + |
| 219 | "use `with { type: 'json' }` for static imports, or pass " + |
| 220 | "`{ with: { type: 'json' } }` as the second argument to dynamic `import()`.", |
| 221 | ); |
| 222 | } |
| 223 | return; |
| 224 | } |
| 225 | if (declaredType !== 'json') { |
| 226 | throw makeImportAttributeError( |
| 227 | 'ERR_IMPORT_ATTRIBUTE_TYPE_INCOMPATIBLE', |
| 228 | `Module "${modulePath}" is not of type "${declaredType}"`, |
| 229 | ); |
| 230 | } |
| 231 | return; |
| 232 | } |
| 233 | |
| 234 | // Non-JSON (implicit-type) module. Per HTML spec, the default type cannot |
| 235 | // be re-asserted, so any explicit `type` attribute is rejected. |
| 236 | if (declaredType !== undefined) { |
| 237 | throw makeImportAttributeError( |
| 238 | 'ERR_IMPORT_ATTRIBUTE_TYPE_INCOMPATIBLE', |
| 239 | `Module "${modulePath}" is not of type "${declaredType}"`, |
| 240 | ); |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | const ESM_TRANSFORM_OPTIONS: TransformOptions = { |
no test coverage detected