@isograph/babel-plugin 0.1.1 → 0.3.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.
@@ -9,29 +9,40 @@ const configExplorer = cosmiconfig('isograph', {
9
9
  '.json': cosmiconfig.loadJson,
10
10
  },
11
11
  });
12
-
12
+ /** @type {NonNullable<import("cosmiconfig").CosmiconfigResult>} */
13
13
  let IsographConfig;
14
14
  const result = configExplorer.searchSync();
15
15
  if (result) {
16
- IsographConfig = result.config;
16
+ IsographConfig = result;
17
17
  } else {
18
18
  throw new Error(
19
19
  'No config found. Do you have a isograph.config.json file somewhere?',
20
20
  );
21
21
  }
22
22
 
23
+ /** @typedef {import("@babel/core")} babel*/
24
+
25
+ /**
26
+ * @typedef {Object} Context
27
+ * @property {typeof babel.types} [types]
28
+ * */
29
+
30
+ /**
31
+ * @param {Context} context
32
+ * @returns {babel.PluginObj} */
23
33
  module.exports = function BabelPluginIsograph(context) {
24
- const { types: t } = context;
25
- if (!t) {
34
+ const { types } = context;
35
+ if (!types) {
26
36
  throw new Error(
27
37
  'BabelPluginIsograph: Expected plugin context to include "types", but got:' +
28
38
  String(context),
29
39
  );
30
40
  }
31
41
 
42
+ /** @type {babel.Visitor<babel.PluginPass>} */
32
43
  const visitor = {
33
44
  CallExpression(path) {
34
- compileTag(t, path, IsographConfig);
45
+ compileTag(types, path, IsographConfig);
35
46
  },
36
47
  };
37
48
 
package/compileTag.js CHANGED
@@ -1,7 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const pathModule = require('path');
4
+ const os = require('os');
4
5
 
6
+ /**
7
+ * @typedef {import("@babel/core")} babel
8
+ * @param {typeof babel.types} t
9
+ * @param {babel.NodePath<babel.types.CallExpression>} path
10
+ * @param {NonNullable<import("cosmiconfig").CosmiconfigResult>} config
11
+ */
5
12
  function compileTag(t, path, config) {
6
13
  const callee = path.node.callee;
7
14
  if (t.isIdentifier(callee) && callee.name === 'iso' && path.node.arguments) {
@@ -10,8 +17,16 @@ function compileTag(t, path, config) {
10
17
  // This throws if the tag is invalid
11
18
  compileImportStatement(t, path, type, field, 'entrypoint', config);
12
19
  } else if (keyword === 'field') {
13
- // No-op
14
- return false;
20
+ if (
21
+ t.isCallExpression(path.parentPath.node) &&
22
+ path.parentPath.node.arguments.length === 1
23
+ ) {
24
+ path.parentPath.replaceWith(path.parentPath.node.arguments[0]);
25
+ } else {
26
+ path.replaceWith(
27
+ t.arrowFunctionExpression([t.identifier('x')], t.identifier('x')),
28
+ );
29
+ }
15
30
  } else {
16
31
  throw new Error(
17
32
  "Invalid iso tag usage. Expected 'entrypoint' or 'field'.",
@@ -26,12 +41,22 @@ const typeAndFieldRegex = new RegExp(
26
41
  'm',
27
42
  );
28
43
 
44
+ /**
45
+ * @param {babel.NodePath<babel.types.CallExpression>} path
46
+ * */
29
47
  function getTypeAndField(path) {
30
48
  if (path.node.arguments.length !== 1) {
31
49
  throw new Error(
32
50
  `BabelPluginIsograph: Iso invocation require one parameter, found ${path.node.arguments.length}`,
33
51
  );
34
52
  }
53
+
54
+ if (path.node.arguments[0].type !== 'TemplateLiteral') {
55
+ throw new Error(
56
+ 'BabelPluginIsograph: Only template literals are allowed in iso fragments.',
57
+ );
58
+ }
59
+
35
60
  const quasis = path.node.arguments[0].quasis;
36
61
  if (quasis.length !== 1) {
37
62
  throw new Error(
@@ -42,9 +67,9 @@ function getTypeAndField(path) {
42
67
  const content = quasis[0].value.raw;
43
68
  const typeAndField = typeAndFieldRegex.exec(content);
44
69
 
45
- const keyword = typeAndField[1];
46
- const type = typeAndField[2];
47
- const field = typeAndField[3];
70
+ const keyword = typeAndField?.[1];
71
+ const type = typeAndField?.[2];
72
+ const field = typeAndField?.[3];
48
73
 
49
74
  if (keyword == null || type == null || field == null) {
50
75
  throw new Error(
@@ -54,13 +79,21 @@ function getTypeAndField(path) {
54
79
  return { keyword, type, field };
55
80
  }
56
81
 
82
+ /**
83
+ * @param {typeof babel.types} t
84
+ * @param {babel.NodePath<babel.types.CallExpression>} path
85
+ * @param {string} type
86
+ * @param {string} field
87
+ * @param {string} artifactType
88
+ * @param {NonNullable<import("cosmiconfig").CosmiconfigResult>} config
89
+ */
57
90
  function compileImportStatement(t, path, type, field, artifactType, config) {
58
91
  const filename = path.state.filename;
59
92
  const folder = pathModule.dirname(filename);
60
- const cwd = path.state.cwd;
93
+ const cwd = pathModule.dirname(config.filepath);
61
94
  const artifactDirectory = pathModule.join(
62
95
  cwd,
63
- config.artifact_directory ?? config.project_root,
96
+ config.config['artifact_directory'] ?? config.config['project_root'],
64
97
  );
65
98
 
66
99
  const fileToArtifactDir = pathModule.relative(folder, artifactDirectory);
@@ -70,6 +103,10 @@ function compileImportStatement(t, path, type, field, artifactType, config) {
70
103
  artifactDirToArtifact,
71
104
  );
72
105
 
106
+ if (os.platform() === 'win32') {
107
+ fileToArtifact = fileToArtifact.replace(/\\/g, '/');
108
+ }
109
+
73
110
  // If we do not have to traverse upward, e.g. if the resolver is in
74
111
  // src/HomePage, and the artifact directory is src/, then fileToArtifact
75
112
  // will start with a /. require('/...') is not good, as that is treated
@@ -80,10 +117,10 @@ function compileImportStatement(t, path, type, field, artifactType, config) {
80
117
 
81
118
  path.replaceWith(
82
119
  t.memberExpression(
83
- t.CallExpression(t.Identifier('require'), [
84
- t.StringLiteral(fileToArtifact),
120
+ t.callExpression(t.identifier('require'), [
121
+ t.stringLiteral(fileToArtifact),
85
122
  ]),
86
- t.Identifier('default'),
123
+ t.identifier('default'),
87
124
  ),
88
125
  );
89
126
  }
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.1.1",
5
+ "version": "0.3.0",
6
6
  "keywords": [
7
7
  "graphql",
8
8
  "isograph",
@@ -15,6 +15,9 @@
15
15
  "url": "git+https://github.com/isographlabs/isograph.git",
16
16
  "directory": "libs/isograph-babel-plugin"
17
17
  },
18
+ "scripts": {
19
+ "tsc": "tsc"
20
+ },
18
21
  "dependencies": {
19
22
  "babel-plugin-macros": "^2.0.0",
20
23
  "cosmiconfig": "^5.0.5",
@@ -22,7 +25,11 @@
22
25
  },
23
26
  "devDependencies": {
24
27
  "@babel/core": "^7.20.0",
28
+ "@babel/types": "^7.25.6",
29
+ "@types/babel__core": "^7.20.5",
30
+ "@types/cosmiconfig": "^5.0.3",
25
31
  "prettier": "2.8.8",
26
32
  "prettier-plugin-hermes-parser": "0.16.0"
27
- }
33
+ },
34
+ "sideEffects": false
28
35
  }
package/stub.ts ADDED
@@ -0,0 +1,6 @@
1
+ import type cosmiconfig from 'cosmiconfig';
2
+ declare module 'cosmiconfig' {
3
+ export const loadJson: cosmiconfig.LoaderEntry;
4
+ }
5
+
6
+ export {};
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.build.json",
3
+ "compilerOptions": {
4
+ "allowJs": true,
5
+ "checkJs": true,
6
+ "noEmit": true,
7
+ "lib": ["es2017", "DOM"]
8
+ },
9
+ "include": ["./**/*.ts", "./**/*.js"]
10
+ }