-
Notifications
You must be signed in to change notification settings - Fork 506
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
question: defaultMetadataStorage is no more available in 0.3.2 #563
Comments
You should be able to reach it from |
Hi, we used defaultMetadataStorage to extract all applied validations so we could construct our OpenAPI schema on the fly. I understand that this is a "private" class of sorts, but we're ready to adapt to any changes, as there is no other way for us to automate OpenAPI generation. edit 1: edit 2: |
Looks like new release changed the npm library definitions to use cjs and other formats to support library package formats. Looks like this is also breaking the package class-validate-jsonschema since it’s also referencing defaultMetadataStorage... |
Yes, we move to the universal package format for each TypeStack package. However, this should not break your workflow as your build tool should be able to understand this as we reference each entry point properly. class-transformer/package.json Lines 9 to 12 in ab093a3
Can I ask what build tools you use @igoreso? |
Trying @igoreso 's workaround produces this error:
I am also not able to see why the "storage" module has vanished from the typescript detection. maybe only the |
It won't be re-exported, because it's an internal part of the lib and we don't support its API officially. I won't actively limit the access to it, but it will be never included in the barrel export to indicate that is not an official API.
It's an internal part of the lib, it will break with future releases. |
What we can do here is update the project config if needed to allow importing it directly with every build tool from its direct path. For that, I will need what build tool cannot find it. |
Nestjs :) In fact, nobody needs to access your internal interface. The only thing we want is the ability to add dynamic Transformer. |
That is misleading. E.g. we need access to the column-mapping somehow. |
same problem here, updating to 0.3.2 breaks the import.
|
You can also import the ES module as declare module 'class-transformer/esm5/storage' {
import type { MetadataStorage } from 'class-transformer/types/MetadataStorage';
export const defaultMetadataStorage: MetadataStorage;
} This is a bit of a hassle though: exposing |
Just wondering @NoNameProvided why you wouldn't want to expose it? One I can contribute to is we are testing our Models to make sure the dto (domain transfer object) don't change
and here are test using it
|
acutally importing it as I shown above failed today. TS 4.1.2 |
Yeah, this is a tooling bug with the new format, I am kind of out of depth here, so I will ask about this on SO and hope someone knows whats up. |
@NoNameProvided is there any plan to make this API public so that other libraries can more easily and reliably interact with class-transformer? |
Also voting to have defaultMetadataStorage as public API. It's very very useful to build advanced features on top of class-transformer. So please add support <3 |
I would also greatly appreciate to have the metadata defaultMetadataStorage as public API. |
any update in here? we really need to use storage for implementing @nestjs/mapped-types in browser |
Fixes error related to typestack/class-transformer#563 that makes it not be able to build --webpack.
I would also greatly appreciate having defaultMetadataStorage as a public API. |
Any update on this? Without exposing the storage or at least exposing methods to retrieve the metadata based on a target any additional tooling won't be able to benefit from the metadata already generated by the decorators provided by class-transformer. |
I support making this public - we need access to it in order to get the metadata. Please make this public, guys. It's really not a big deal. When I attempt to
|
Any updates? Would be good to prioritize this issue as it prevents class transformer from being used in new projects. |
Kindly make |
Importing it like this in my ts file worked for Me :)
class-transformer v. 0.5.1 |
I also cannot load it, the import mentioned didn't work for me. Any luck making it public? |
In a deno project it worked for me only via commonjs import 🤷♂️ // @ts-ignore
import { defaultMetadataStorage } from "npm:class-transformer@0.5.1/cjs/storage.js"; |
This works for me in version
While I've read the entire thread above. It wasn't clear the import problem had been fixed and this issue is still open. Also, while I appreciate this is an internal feature of the library. It's not mentioned in the README file, and if you're like me going to Google or going to ChatGPT for a solution of "how do I get the metadata at run-time" then there is a lot of public information pointing to this function as a feature of the library. It would be nice, if a footnote could be added to the README explaining how to import the method with a stern warning that it's not an official part of the API and subject to change. That would be good enough for most use cases. |
@codemile Thanks your discovery, but your solution is incompatible with
|
Any chance metadata will be exported? My use case is to get an |
Hi , i'm not sure which is correct or not, i try : import { MetadataStorage } from "class-transformer/types/MetadataStorage";
...
const schemas = validationMetadatasToSchemas({
// classTransformerMetadataStorage: defaultMetadataStorage,
classTransformerMetadataStorage: new MetadataStorage(),
refPointerPrefix: "#/components/schemas/",
}); I read this and found it just new MetadataStorage() and export |
This is so dumb that this was excluded that I can not even imagine. |
It looks like there is an open PR already here #1715, can this be moved forward? 🙏 |
We would also benefit from this PR being merged 🙏 |
For anyone that needs it, the intermediate solution right now for us has been to use:
but this may require additional configuration and it would be much better if we can just do:
|
It would be great to have this PR merged, as the |
Meanwhile, as a hacky workaround I created a post install script to modify the files installed by npm to expose storage. Note: the patch covers our use case but doesn't care about the bundled /**
* @author Javier Muñoz Tous <javimtib92@gmail.com>
*
* class-transformer version 0.5.1 patch
*
* This patch aims to address an inconvenience introduced in class-transformer version 0.3.2 making storage module no longer
* exposed as a public module.
*
* While we wait for this PR to be merged [feat(export): export defaultMetadataStorage](https://github.com/typestack/class-transformer/pull/1715)
* we decided to introduce this patch as a quick workaround to avoid importing the customjs version of the class-transformer files in vite.
*
*/
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __dirname = getDirname();
(() => {
const nodeModulesDir = path.join(findRootWithPackageJson(), "node_modules");
const classTransformerDir = path.join(nodeModulesDir, "class-transformer");
const classTransformerPackageFile = getPackageJson(classTransformerDir);
if (classTransformerPackageFile.version !== "0.5.1") {
console.warn("Warning: class-transformer-0.5.1.patch is being applied to a different version. Please verify if this patch is still necessary.");
}
const items = fs.readdirSync(classTransformerDir);
// Iterate over the items and filter only directories
for (const item of items) {
const itemPath = path.join(classTransformerDir, item);
if (!fs.statSync(itemPath).isDirectory()) {
continue;
}
const subItems = fs.readdirSync(itemPath);
for (const subItem of subItems) {
const subItemPath = path.join(itemPath, subItem);
// Check if the subItem is a file and does not have the .map extension
if (fs.statSync(subItemPath).isFile() && subItem.startsWith("index") && path.extname(subItem) !== ".map" && path.extname(subItem) !== ".ts") {
let fileContent = fs.readFileSync(subItemPath, "utf-8");
let modifiedContent = fileContent;
const comment = `/**\n * This file has been modified by patch "class-transformer-0.5.1.patch.js.\n * The patch introduces changes to append storage exports in 'cjs', 'esm5', and 'esm2025' module types.\n */\n\n`;
if (!fileContent.startsWith(comment)) {
modifiedContent = comment + modifiedContent;
} else {
// If patch was already applied to this file we exit early
console.error(`Patch class-transformer-0.5.1.patch is already applied. Skipping...`);
return;
}
switch (item) {
case "cjs": {
const searchLine = '__exportStar(require("./enums"), exports);';
const appendLine = '__exportStar(require("./storage"), exports);';
if (fileContent.includes(searchLine)) {
modifiedContent = modifiedContent.replace(searchLine, `${searchLine}\n${appendLine}`);
}
break;
}
case "esm5":
case "esm2015": {
const searchLine = "export * from './enums';";
const appendLine = "export * from './storage';";
if (fileContent.includes(searchLine)) {
modifiedContent = modifiedContent.replace(searchLine, `${searchLine}\n${appendLine}`);
}
break;
}
}
if (modifiedContent.length !== fileContent.length) {
fs.writeFileSync(subItemPath, modifiedContent, "utf-8");
}
}
}
}
console.log(`\x1b[32m Applied class-transformer-0.5.1.patch \x1b[0m`);
})();
function getDirname() {
try {
return __dirname;
} catch {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
return __dirname;
}
}
function getPackageJson(currentDir = __dirname) {
const packageJsonPath = path.join(currentDir, "package.json");
if (fs.existsSync(packageJsonPath)) {
const content = fs.readFileSync(packageJsonPath, "utf-8");
const packageJson = JSON.parse(content);
return packageJson;
} else {
throw new Error("class-transformer package not found");
}
}
/**
* Search the neareast directory that contains a package.json file.
* @param {string} currentDir
* @returns
*/
function findRootWithPackageJson(currentDir = __dirname) {
const packagePath = path.join(currentDir, "package.json");
if (fs.existsSync(packagePath)) {
return currentDir;
}
const parentDir = path.resolve(currentDir, "..");
if (parentDir === currentDir) {
throw new Error("package.json not found in any parent directory");
}
return findRootWithPackageJson(parentDir);
} You can add this script to the post install script like so: "scripts": {
"postinstall": "node scripts/patches/class-transformer-0.5.1.patch.js",
},
|
Description
In the previous version it was possible to access to the defaultMetadataStorage which was useful to create custom transformer.
for example :
Minimal code-snippet showcasing the problem
Expected behavior
Get the defaultMetadataStorage !
Actual behavior
"Cannot find module 'class-transformer/storage' or its corresponding type declarations."
The text was updated successfully, but these errors were encountered: