New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@graphox/babel-plugin

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@graphox/babel-plugin - npm Package Compare versions

Comparing version
0.4.0
to
0.4.1
+61
-16
index.js

@@ -238,2 +238,13 @@ const path = require('path');

importPath.get('specifiers').forEach((specifier) => {
if (specifier.isImportDefaultSpecifier() || specifier.isImportNamespaceSpecifier()) {
if (!importIsTypeOnly) {
const importKind = specifier.isImportDefaultSpecifier() ? 'default' : 'namespace';
throw specifier.buildCodeFrameError(
`@graphox/babel-plugin could not fully rewrite this ${importKind} import from "${src}". ` +
'Only named document imports and graphql/gql are supported.',
);
}
return;
}
if (specifier.isImportSpecifier()) {

@@ -278,2 +289,7 @@ // Handle both Identifier and StringLiteral for imported name

}
} else if (!specifierIsTypeOnly) {
throw specifier.buildCodeFrameError(
`@graphox/babel-plugin could not rewrite "${importedName}" from "${src}". ` +
'Run Graphox codegen and ensure the manifest includes this document.',
);
}

@@ -304,20 +320,30 @@ }

if (source) {
const normalizedSource = normalize(source);
const entry = manifest.get(normalizedSource);
if (entry) {
const codegenAbsPath = path.join(absoluteOutputDir, entry.path);
let relPath = path.relative(path.dirname(currentFile), codegenAbsPath);
relPath = toPosixPath(relPath);
if (!relPath.startsWith('.') && !path.isAbsolute(relPath)) {
relPath = './' + relPath;
}
// Append the emit extension
relPath += extension;
if (!source) {
throw callPath.buildCodeFrameError(
`@graphox/babel-plugin could not statically analyze this ${callee.node.name}() call. ` +
'Use a single static string/template literal so it can be resolved from the manifest.',
);
}
const uniqueLocalName = getLocalName(entry.name, callPath.scope);
newImports.set(uniqueLocalName, { sourcePath: relPath, importedName: entry.name });
callPath.replaceWith(t.identifier(uniqueLocalName));
}
const normalizedSource = normalize(source);
const entry = manifest.get(normalizedSource);
if (!entry) {
throw callPath.buildCodeFrameError(
`@graphox/babel-plugin could not find this ${callee.node.name}() document in the manifest. ` +
'Run Graphox codegen and ensure the build is using the correct manifest.',
);
}
const codegenAbsPath = path.join(absoluteOutputDir, entry.path);
let relPath = path.relative(path.dirname(currentFile), codegenAbsPath);
relPath = toPosixPath(relPath);
if (!relPath.startsWith('.') && !path.isAbsolute(relPath)) {
relPath = './' + relPath;
}
// Append the emit extension
relPath += extension;
const uniqueLocalName = getLocalName(entry.name, callPath.scope);
newImports.set(uniqueLocalName, { sourcePath: relPath, importedName: entry.name });
callPath.replaceWith(t.identifier(uniqueLocalName));
}

@@ -328,2 +354,21 @@ }

// Ensure we never remove the entrypoint import while runtime references still exist.
programPath.traverse({
Identifier(idPath) {
if (!idPath.isReferencedIdentifier()) {
return;
}
const binding = idPath.scope.getBinding(idPath.node.name);
if (!binding || !graphqlIds.has(binding)) {
return;
}
throw idPath.buildCodeFrameError(
`@graphox/babel-plugin left a runtime reference to "${idPath.node.name}" after rewriting. ` +
'All Graphox graphql/gql imports must be fully inlined before the import is removed.',
);
},
});
// Third pass: remove ALL imports from graphql.ts/index.ts

@@ -330,0 +375,0 @@ programPath.traverse({

@@ -67,12 +67,9 @@ import { describe, it, expect } from 'vitest';

it('removes all imports from graphql.ts including unknown specifiers', () => {
const code = "import { graphql, other } from './gen/graphql'; const q = graphql(`query { me { id } }`);";
const output = transform(code, defaultOptions);
it('throws when a value import from graphql.ts cannot be rewritten', () => {
const code = "import { graphql, other } from './gen/graphql'; const q = graphql(`query { me { id } }`); console.log(other);";
expect(output).toContain('import { MyQueryDocument } from "./gen/query.codegen";');
expect(output).not.toContain('from "./gen/graphql"');
expect(output).not.toContain('graphql,');
expect(output).not.toContain(', graphql');
expect(output).not.toContain('other');
});
expect(() => transform(code, defaultOptions)).toThrow(
/could not rewrite "other" from "\.\/gen\/graphql"/,
);
});

@@ -109,11 +106,43 @@ it('resolves relative paths correctly', () => {

it('supports gql tag', () => {
const code = "import { gql } from './gen/graphql'; const q = gql(`query { me { id } }`);";
const output = transform(code, defaultOptions);
it('supports gql tag', () => {
const code = "import { gql } from './gen/graphql'; const q = gql(`query { me { id } }`);";
const output = transform(code, defaultOptions);
expect(output).toContain('import { MyQueryDocument } from "./gen/query.codegen";');
expect(output).toContain('const q = MyQueryDocument;');
expect(output).not.toContain('from "./gen/graphql"');
});
expect(output).toContain('const q = MyQueryDocument;');
expect(output).not.toContain('from "./gen/graphql"');
});
it('throws when graphql() is missing from the manifest', () => {
const code = "import { graphql } from './gen/graphql'; const q = graphql(`query Missing { me { id } }`);";
expect(() => transform(code, defaultOptions)).toThrow(
/could not find this graphql\(\) document in the manifest/i,
);
});
it('throws when graphql() is not a single static string', () => {
const code = `
import { graphql } from './gen/graphql';
const query = 'query { me { id } }';
const q = graphql(query);
`;
expect(() => transform(code, defaultOptions)).toThrow(
/could not statically analyze this graphql\(\) call/i,
);
});
it('throws when a graphql import is still referenced after rewriting', () => {
const code = `
import { graphql } from './gen/graphql';
const tag = graphql;
console.log(tag);
`;
expect(() => transform(code, defaultOptions)).toThrow(
/left a runtime reference to "graphql" after rewriting/i,
);
});
it('is whitespace insensitive (normalization)', () => {

@@ -281,9 +310,8 @@ const code = `

it('removes non-document imports while rewriting document imports', () => {
it('throws on non-document imports alongside rewritten document imports', () => {
const code = "import { GetUserDocument, SomeOtherType } from './gen/graphql';";
const output = transform(code, reExportOptions);
expect(output).toContain("import { GetUserDocument } from \"./gen/user.codegen\";");
expect(output).not.toContain("from './gen/graphql'");
expect(output).not.toContain('SomeOtherType');
expect(() => transform(code, reExportOptions)).toThrow(
/could not rewrite "SomeOtherType" from "\.\/gen\/graphql"/,
);
});

@@ -290,0 +318,0 @@

{
"name": "@graphox/babel-plugin",
"version": "0.4.0",
"version": "0.4.1",
"description": "Babel plugin for Graphox codesplitting",

@@ -5,0 +5,0 @@ "main": "index.js",