@isograph/babel-plugin 0.3.1 → 0.4.0
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/BabelPluginIsograph.test.js +97 -0
- package/compileTag.js +27 -14
- package/package.json +3 -2
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { transform } from '@babel/core';
|
|
2
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
3
|
+
import plugin from './BabelPluginIsograph';
|
|
4
|
+
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
async function mock(mockedUri, stub) {
|
|
7
|
+
const { Module } = await import('module');
|
|
8
|
+
const path = await import('path');
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
Module._load_original = Module._load;
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
Module._load = (uri, parent) => {
|
|
13
|
+
if (uri === mockedUri) return stub(path);
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
return Module._load_original(uri, parent);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// In order to test `require`
|
|
20
|
+
vi.hoisted(
|
|
21
|
+
() =>
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
void mock('cosmiconfig', (path) => () => ({
|
|
24
|
+
searchSync: () => ({
|
|
25
|
+
config: {
|
|
26
|
+
project_root: './src/components',
|
|
27
|
+
schema: './backend/schema.graphql',
|
|
28
|
+
schema_extensions: ['./backend/schema-extension.graphql'],
|
|
29
|
+
options: {
|
|
30
|
+
module: 'esmodule',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
filepath: `${path.resolve('.')}/isograph.config.json`,
|
|
34
|
+
}),
|
|
35
|
+
})),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
describe('Babel plugin Isograph', () => {
|
|
39
|
+
const transformerOpts = {
|
|
40
|
+
babelrc: false,
|
|
41
|
+
filename: './src/components/Home/Header/File.ts',
|
|
42
|
+
plugins: [[plugin, {}]],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
test('should return an identity for non called iso function', () => {
|
|
46
|
+
const code = `
|
|
47
|
+
export const HomeRoute = iso(\`
|
|
48
|
+
field Query.HomeRoute @component {
|
|
49
|
+
pets {
|
|
50
|
+
id
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
\`);
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
const result = transform(code, transformerOpts) ?? { code: '' };
|
|
57
|
+
|
|
58
|
+
expect(result.code).toMatchInlineSnapshot(
|
|
59
|
+
`"export const HomeRoute = x => x;"`,
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('should preserve function call when iso applied', () => {
|
|
64
|
+
const code = `
|
|
65
|
+
export const HomeRoute = iso(\`
|
|
66
|
+
field Query.HomeRoute @component {
|
|
67
|
+
pets {
|
|
68
|
+
id
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
\`)(function HomeRouteComponent() {
|
|
72
|
+
return 'Render';
|
|
73
|
+
});
|
|
74
|
+
`;
|
|
75
|
+
|
|
76
|
+
const result = transform(code, transformerOpts) ?? { code: '' };
|
|
77
|
+
|
|
78
|
+
expect(result.code).toMatchInlineSnapshot(`
|
|
79
|
+
"export const HomeRoute = function HomeRouteComponent() {
|
|
80
|
+
return 'Render';
|
|
81
|
+
};"
|
|
82
|
+
`);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('should transform the iso function to a require call', () => {
|
|
86
|
+
const code = `function test() { const a=iso(\`entrypoint Query.HomeRoute\`); }`;
|
|
87
|
+
|
|
88
|
+
const result = transform(code, transformerOpts) ?? { code: '' };
|
|
89
|
+
|
|
90
|
+
expect(result.code).toMatchInlineSnapshot(`
|
|
91
|
+
"import _HomeRoute from "../../__isograph/Query/HomeRoute/entrypoint.ts";
|
|
92
|
+
function test() {
|
|
93
|
+
const a = _HomeRoute;
|
|
94
|
+
}"
|
|
95
|
+
`);
|
|
96
|
+
});
|
|
97
|
+
});
|
package/compileTag.js
CHANGED
|
@@ -13,11 +13,19 @@ const os = require('os');
|
|
|
13
13
|
function compileTag(t, path, config) {
|
|
14
14
|
const callee = path.node.callee;
|
|
15
15
|
if (t.isIdentifier(callee) && callee.name === 'iso' && path.node.arguments) {
|
|
16
|
-
const { keyword,
|
|
16
|
+
const { keyword, parentObjectEntityName, selectableName } =
|
|
17
|
+
getParentObjectEntityNameAndSelectableName(path);
|
|
17
18
|
if (keyword === 'entrypoint') {
|
|
18
19
|
// This throws if the tag is invalid
|
|
19
|
-
compileImportStatement(
|
|
20
|
-
|
|
20
|
+
compileImportStatement(
|
|
21
|
+
t,
|
|
22
|
+
path,
|
|
23
|
+
parentObjectEntityName,
|
|
24
|
+
selectableName,
|
|
25
|
+
'entrypoint',
|
|
26
|
+
config,
|
|
27
|
+
);
|
|
28
|
+
} else if (keyword === 'field' || keyword === 'pointer') {
|
|
21
29
|
if (t.isCallExpression(path.parentPath.node)) {
|
|
22
30
|
const firstArg = path.parentPath.node.arguments[0];
|
|
23
31
|
if (path.parentPath.node.arguments.length === 1 && firstArg != null) {
|
|
@@ -34,22 +42,22 @@ function compileTag(t, path, config) {
|
|
|
34
42
|
}
|
|
35
43
|
} else {
|
|
36
44
|
throw new Error(
|
|
37
|
-
"Invalid iso tag usage. Expected 'entrypoint' or '
|
|
45
|
+
"Invalid iso tag usage. Expected 'entrypoint', 'field' or 'pointer'.",
|
|
38
46
|
);
|
|
39
47
|
}
|
|
40
48
|
}
|
|
41
49
|
return false;
|
|
42
50
|
}
|
|
43
51
|
|
|
44
|
-
const
|
|
45
|
-
'\\s*(entrypoint|field)\\s*([^\\.\\s]+)\\.([^\\s\\(]+)',
|
|
52
|
+
const parentObjectEntityNameAndSelectableNameRegex = new RegExp(
|
|
53
|
+
'\\s*(entrypoint|field|pointer)\\s*([^\\.\\s]+)\\.([^\\s\\(]+)',
|
|
46
54
|
'm',
|
|
47
55
|
);
|
|
48
56
|
|
|
49
57
|
/**
|
|
50
58
|
* @param {babel.NodePath<babel.types.CallExpression>} path
|
|
51
|
-
|
|
52
|
-
function
|
|
59
|
+
**/
|
|
60
|
+
function getParentObjectEntityNameAndSelectableName(path) {
|
|
53
61
|
const firstArg = path.node.arguments[0];
|
|
54
62
|
if (path.node.arguments.length !== 1 || firstArg == null) {
|
|
55
63
|
throw new Error(
|
|
@@ -72,18 +80,23 @@ function getTypeAndField(path) {
|
|
|
72
80
|
}
|
|
73
81
|
|
|
74
82
|
const content = firstQuasi.value.raw;
|
|
75
|
-
const typeAndField =
|
|
83
|
+
const typeAndField =
|
|
84
|
+
parentObjectEntityNameAndSelectableNameRegex.exec(content);
|
|
76
85
|
|
|
77
86
|
const keyword = typeAndField?.[1];
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
if (
|
|
87
|
+
const parentObjectEntityName = typeAndField?.[2];
|
|
88
|
+
const selectableName = typeAndField?.[3];
|
|
89
|
+
|
|
90
|
+
if (
|
|
91
|
+
keyword == null ||
|
|
92
|
+
parentObjectEntityName == null ||
|
|
93
|
+
selectableName == null
|
|
94
|
+
) {
|
|
82
95
|
throw new Error(
|
|
83
96
|
'Malformed iso literal. I hope the iso compiler failed to accept this literal!',
|
|
84
97
|
);
|
|
85
98
|
}
|
|
86
|
-
return { keyword,
|
|
99
|
+
return { keyword, parentObjectEntityName, selectableName };
|
|
87
100
|
}
|
|
88
101
|
|
|
89
102
|
/**
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@isograph/babel-plugin",
|
|
3
3
|
"description": "A Babel plugin for use with Isograph applications.",
|
|
4
4
|
"homepage": "https://isograph.dev",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.4.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"graphql",
|
|
8
8
|
"isograph",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
19
|
"tsc": "tsc",
|
|
20
|
-
"tsc-force": "tsc --build --clean && tsc --build --force"
|
|
20
|
+
"tsc-force": "tsc --build --clean && tsc --build --force",
|
|
21
|
+
"test": "vitest run"
|
|
21
22
|
},
|
|
22
23
|
"dependencies": {
|
|
23
24
|
"@babel/helper-module-imports": "^7.0.0",
|