From e7bb32b0b90fbf6d797819c504ad9308c56e5f39 Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Wed, 31 Jul 2024 14:35:40 +0200 Subject: [PATCH] Modernize --- .eslintrc | 34 - Makefile | 12 +- README.md | 6 +- bin/json-graphql-server.cjs | 5 +- biome.json | 27 + example/{data.js => data.cjs} | 0 package.json | 42 +- src/{client.js => client.ts} | 0 src/createApolloClient.js | 13 - src/createApolloClient.ts | 15 + src/global.d.ts | 7 + ...ClientServer.js => graphQLClientServer.ts} | 5 +- ...{graphiqlHandler.js => graphiqlHandler.ts} | 10 +- src/{handleRequest.js => handleRequest.ts} | 9 +- .../{DateType.js => DateType.ts} | 16 +- ....spec.js => getFieldsFromEntities.spec.ts} | 2 +- ...omEntities.js => getFieldsFromEntities.ts} | 30 +- ...spec.js => getFilterTypesFromData.spec.ts} | 0 ...sFromData.js => getFilterTypesFromData.ts} | 62 +- src/introspection/getSchemaFromData.js | 216 - ...Data.spec.js => getSchemaFromData.spec.ts} | 128 +- src/introspection/getSchemaFromData.ts | 237 + ...lues.spec.js => getTypeFromValues.spec.ts} | 22 +- ...TypeFromValues.js => getTypeFromValues.ts} | 51 +- ...mData.spec.js => getTypesFromData.spec.ts} | 0 ...etTypesFromData.js => getTypesFromData.ts} | 5 +- ....spec.js => getValuesFromEntities.spec.ts} | 4 +- ...omEntities.js => getValuesFromEntities.ts} | 8 +- src/introspection/hasType.js | 10 - src/introspection/hasType.ts | 19 + ...ess.spec.js => jsonGraphqlExpress.spec.ts} | 12 +- ...raphqlExpress.js => jsonGraphqlExpress.ts} | 10 +- src/{nameConverter.js => nameConverter.ts} | 10 +- src/{node.js => node.ts} | 3 +- src/relationships.js | 1 - src/relationships.ts | 2 + .../Entity/{index.spec.js => index.spec.ts} | 0 src/resolver/Entity/{index.js => index.ts} | 22 +- src/resolver/Mutation/create.js | 7 - .../{create.spec.js => create.spec.ts} | 0 src/resolver/Mutation/create.ts | 12 + src/resolver/Mutation/createMany.js | 5 - ...{createMany.spec.js => createMany.spec.ts} | 0 src/resolver/Mutation/createMany.ts | 7 + src/resolver/Mutation/remove.js | 14 - .../{remove.spec.js => remove.spec.ts} | 0 src/resolver/Mutation/remove.ts | 17 + src/resolver/Mutation/update.js | 18 - .../{update.spec.js => update.spec.ts} | 2 +- src/resolver/Mutation/update.ts | 21 + src/resolver/Query/all.js | 29 - .../Query/{all.spec.js => all.spec.ts} | 4 +- src/resolver/Query/all.ts | 44 + ...lyFilters.spec.js => applyFilters.spec.ts} | 20 +- .../{applyFilters.js => applyFilters.ts} | 46 +- src/resolver/Query/meta.js | 7 - src/resolver/Query/meta.ts | 9 + src/resolver/Query/single.js | 2 - .../Query/{single.spec.js => single.spec.ts} | 0 src/resolver/Query/single.ts | 6 + src/resolver/{index.js => index.ts} | 19 +- ...aBuilder.spec.js => schemaBuilder.spec.ts} | 99 +- src/{schemaBuilder.js => schemaBuilder.ts} | 6 +- src/types.ts | 3 + src/utils.js | 58 - tsconfig.json | 26 + vite.config.node.js => vite.config.node.ts | 4 +- vite.config.js => vite.config.ts | 16 +- vite.config.umd.js => vite.config.umd.ts | 5 +- yarn.lock | 3912 ++--------------- 70 files changed, 1192 insertions(+), 4281 deletions(-) delete mode 100644 .eslintrc create mode 100644 biome.json rename example/{data.js => data.cjs} (100%) rename src/{client.js => client.ts} (100%) delete mode 100644 src/createApolloClient.js create mode 100644 src/createApolloClient.ts create mode 100644 src/global.d.ts rename src/{graphQLClientServer.js => graphQLClientServer.ts} (94%) rename src/{graphiqlHandler.js => graphiqlHandler.ts} (92%) rename src/{handleRequest.js => handleRequest.ts} (90%) rename src/introspection/{DateType.js => DateType.ts} (76%) rename src/introspection/{getFieldsFromEntities.spec.js => getFieldsFromEntities.spec.ts} (97%) rename src/introspection/{getFieldsFromEntities.js => getFieldsFromEntities.ts} (59%) rename src/introspection/{getFilterTypesFromData.spec.js => getFilterTypesFromData.spec.ts} (100%) rename src/introspection/{getFilterTypesFromData.js => getFilterTypesFromData.ts} (67%) delete mode 100644 src/introspection/getSchemaFromData.js rename src/introspection/{getSchemaFromData.spec.js => getSchemaFromData.spec.ts} (59%) create mode 100644 src/introspection/getSchemaFromData.ts rename src/introspection/{getTypeFromValues.spec.js => getTypeFromValues.spec.ts} (92%) rename src/introspection/{getTypeFromValues.js => getTypeFromValues.ts} (61%) rename src/introspection/{getTypesFromData.spec.js => getTypesFromData.spec.ts} (100%) rename src/introspection/{getTypesFromData.js => getTypesFromData.ts} (93%) rename src/introspection/{getValuesFromEntities.spec.js => getValuesFromEntities.spec.ts} (97%) rename src/introspection/{getValuesFromEntities.js => getValuesFromEntities.ts} (81%) delete mode 100644 src/introspection/hasType.js create mode 100644 src/introspection/hasType.ts rename src/{jsonGraphqlExpress.spec.js => jsonGraphqlExpress.spec.ts} (94%) rename src/{jsonGraphqlExpress.js => jsonGraphqlExpress.ts} (82%) rename src/{nameConverter.js => nameConverter.ts} (78%) rename src/{node.js => node.ts} (73%) delete mode 100644 src/relationships.js create mode 100644 src/relationships.ts rename src/resolver/Entity/{index.spec.js => index.spec.ts} (100%) rename src/resolver/Entity/{index.js => index.ts} (78%) delete mode 100644 src/resolver/Mutation/create.js rename src/resolver/Mutation/{create.spec.js => create.spec.ts} (100%) create mode 100644 src/resolver/Mutation/create.ts delete mode 100644 src/resolver/Mutation/createMany.js rename src/resolver/Mutation/{createMany.spec.js => createMany.spec.ts} (100%) create mode 100644 src/resolver/Mutation/createMany.ts delete mode 100644 src/resolver/Mutation/remove.js rename src/resolver/Mutation/{remove.spec.js => remove.spec.ts} (100%) create mode 100644 src/resolver/Mutation/remove.ts delete mode 100644 src/resolver/Mutation/update.js rename src/resolver/Mutation/{update.spec.js => update.spec.ts} (99%) create mode 100644 src/resolver/Mutation/update.ts delete mode 100644 src/resolver/Query/all.js rename src/resolver/Query/{all.spec.js => all.spec.ts} (99%) create mode 100644 src/resolver/Query/all.ts rename src/resolver/Query/{applyFilters.spec.js => applyFilters.spec.ts} (97%) rename src/resolver/Query/{applyFilters.js => applyFilters.ts} (74%) delete mode 100644 src/resolver/Query/meta.js create mode 100644 src/resolver/Query/meta.ts delete mode 100644 src/resolver/Query/single.js rename src/resolver/Query/{single.spec.js => single.spec.ts} (100%) create mode 100644 src/resolver/Query/single.ts rename src/resolver/{index.js => index.ts} (81%) rename src/{schemaBuilder.spec.js => schemaBuilder.spec.ts} (71%) rename src/{schemaBuilder.js => schemaBuilder.ts} (90%) create mode 100644 src/types.ts delete mode 100644 src/utils.js create mode 100644 tsconfig.json rename vite.config.node.js => vite.config.node.ts (87%) rename vite.config.js => vite.config.ts (54%) rename vite.config.umd.js => vite.config.umd.ts (81%) diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index f32a8ab..0000000 --- a/.eslintrc +++ /dev/null @@ -1,34 +0,0 @@ -{ - "parser": "babel-eslint", - "env": { - "browser": true, - "es6": true, - "mocha": true, - "node": true, - "jest/globals": true - }, - "extends": [ - "eslint:recommended", - "prettier", - "plugin:prettier/recommended", - "plugin:import/errors", - "plugin:import/warnings" - ], - "plugins": ["prettier", "jest"], - "rules": { - "prettier/prettier": ["error"], - "import/no-extraneous-dependencies": "off", - "no-console": [ - "error", - { - "allow": ["warn", "error"] - } - ], - "no-unused-vars": [ - "error", - { - "ignoreRestSiblings": true - } - ] - } -} diff --git a/Makefile b/Makefile index 86e9a48..44952e7 100644 --- a/Makefile +++ b/Makefile @@ -13,18 +13,16 @@ watch: ## continuously compile ES6 files to JS @yarn vite build --watch test: ## Launch unit tests - @NODE_ENV=test NODE_OPTIONS="$$NODE_OPTIONS --experimental-vm-modules" ./node_modules/.bin/jest + @yarn run test watch-test: ## Launch unit tests and watch for changes - @NODE_ENV=test NODE_OPTIONS="$$NODE_OPTIONS --experimental-vm-modules" ./node_modules/.bin/jest --watch + @yarn run watch-test format: ## Format the source code - @./node_modules/.bin/eslint --fix ./src + @yarn run format run: ## Launch server with example data - @node ./bin/json-graphql-server.js example/data.js + @yarn run server build: ## Build production release - @yarn vite build - @yarn vite build -c ./vite.config.node.js - @yarn vite build -c ./vite.config.umd.js + @yarn run build diff --git a/README.md b/README.md index de60632..518e9b5 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ module.exports = { Start the GraphQL server on localhost, port 3000. ```sh -json-graphql-server db.js +npx json-graphql-server db.js ``` To use a port other than 3000, you can run `json-graphql-server db.js --p ` @@ -98,7 +98,7 @@ Note that the server is [GraphiQL](https://github.com/graphql/graphiql) enabled, ## Install ```sh -npm install -g json-graphql-server +npm install -D json-graphql-server ``` ## Generated Types and Queries @@ -448,7 +448,7 @@ Then use the `jsonGraphqlExpress` express middleware: ```js import express from 'express'; -import jsonGraphqlExpress from 'json-graphql-server/node'; +import { jsonGraphqlExpress } from 'json-graphql-server/node'; const PORT = 3000; const app = express(); diff --git a/bin/json-graphql-server.cjs b/bin/json-graphql-server.cjs index 1437858..703209c 100755 --- a/bin/json-graphql-server.cjs +++ b/bin/json-graphql-server.cjs @@ -1,9 +1,8 @@ #!/usr/bin/env node -require('reify'); var path = require('path'); var express = require('express'); var cors = require('cors'); -var JsonGraphqlServer = require('../dist/json-graphql-server-node.cjs').default; +var { jsonGraphqlExpress } = require('../dist/json-graphql-server-node.cjs'); var dataFilePath = process.argv.length > 2 ? process.argv[2] : './data.json'; var data = require(path.join(process.cwd(), dataFilePath)); var PORT = process.env.NODE_PORT || 3000; @@ -22,7 +21,7 @@ process.argv.forEach((arg, index) => { }); app.use(cors()); -app.use('/', JsonGraphqlServer(data)); +app.use('/', jsonGraphqlExpress(data)); app.listen(PORT, HOST); var msg = `GraphQL server running with your data at http://${HOST}:${PORT}/`; console.log(msg); // eslint-disable-line no-console diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..9a45182 --- /dev/null +++ b/biome.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.7.0/schema.json", + "organizeImports": { + "enabled": true + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 4, + "ignore": ["public/*.js"] + }, + "javascript": { + "formatter": { + "quoteStyle": "single" + } + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "suspicious": { + "noExplicitAny": "off" + } + }, + "ignore": ["public/*.js"] + } +} diff --git a/example/data.js b/example/data.cjs similarity index 100% rename from example/data.js rename to example/data.cjs diff --git a/package.json b/package.json index 087cd68..7356e2c 100644 --- a/package.json +++ b/package.json @@ -27,34 +27,34 @@ ], "license": "MIT", "scripts": { - "format": "make format", + "format": "biome format --write src", + "lint": "biome lint --apply src", "precommit": "lint-staged", - "test": "jest", - "watch-test": "make watch-test", - "server": "make run", - "prepublish": "make build" + "test": "cross-env NODE_ENV=test vitest", + "server": "node ./bin/json-graphql-server.js example/data.js", + "prepublish": "yarn build", + "build": "yarn build-ts && yarn build-esm-cjs && yarn build-node && yarn build-umd", + "build-ts": "tsc", + "build-esm-cjs": "vite build", + "build-node": "vite build -c ./vite.config.node.js", + "build-umd": "vite build -c ./vite.config.umd.js" }, "lint-staged": { - "src/**/*.js": [ - "eslint --fix", - "git add" + "*.{js,jsx,ts,tsx}": [ + "biome lint --apply", + "biome format --write" ] }, "devDependencies": { - "@types/jest": "^29.5.12", - "babel-eslint": "^10.0.3", - "babel-jest": "^29.7.0", - "eslint": "^9.0.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jest": "^28.2.0", - "eslint-plugin-prettier": "^5.1.3", + "@biomejs/biome": "1.7.0", + "@types/express": "^4.17.21", + "cross-env": "^7.0.3", "husky": "^9.0.11", - "jest": "^29.7.0", "lint-staged": "^15.2.2", - "prettier": "^3.2.5", "supertest": "^6.3.4", - "vite": "^5.2.8" + "typescript": "^5.5.4", + "vite": "^5.2.8", + "vitest": "^2.0.5" }, "dependencies": { "@apollo/client": "^3.9.11", @@ -63,14 +63,12 @@ "express": "^4.17.3", "graphql": "^16.8.1", "graphql-http": "^1.22.1", - "graphql-tag": "^2.12.6", "graphql-type-json": "^0.3.2", "inflection": "^3.0.0", "lodash.merge": "^4.6.2", - "reify": "^0.20.12", "xhr-mock": "^2.5.1" }, "bin": { "json-graphql-server": "bin/json-graphql-server.cjs" } -} \ No newline at end of file +} diff --git a/src/client.js b/src/client.ts similarity index 100% rename from src/client.js rename to src/client.ts diff --git a/src/createApolloClient.js b/src/createApolloClient.js deleted file mode 100644 index b18dc24..0000000 --- a/src/createApolloClient.js +++ /dev/null @@ -1,13 +0,0 @@ -import { ApolloClient, mockNetworkInterfaceWithSchema } from '@apollo/client'; -import getSchemaFromData from './introspection/getSchemaFromData'; - -export default (data) => { - const schema = getSchemaFromData(data); - const mockNetworkInterface = mockNetworkInterfaceWithSchema({ schema }); - - const client = new ApolloClient({ - networkInterface: mockNetworkInterface, - }); - - return client; -}; diff --git a/src/createApolloClient.ts b/src/createApolloClient.ts new file mode 100644 index 0000000..f1627bc --- /dev/null +++ b/src/createApolloClient.ts @@ -0,0 +1,15 @@ +import { ApolloClient, InMemoryCache } from '@apollo/client'; +import { SchemaLink } from '@apollo/client/link/schema'; +import getSchemaFromData from './introspection/getSchemaFromData'; +import type { Data } from './types'; + +export default (data: Data) => { + const schema = getSchemaFromData(data); + + const client = new ApolloClient({ + cache: new InMemoryCache(), + link: new SchemaLink({ schema }), + }); + + return client; +}; diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 0000000..c769513 --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1,7 @@ +declare global { + interface Window { + JsonGraphqlServer: object; + jsonSchemaBuilder: object; + } +} +export default global; diff --git a/src/graphQLClientServer.js b/src/graphQLClientServer.ts similarity index 94% rename from src/graphQLClientServer.js rename to src/graphQLClientServer.ts index bbe07cf..d309029 100644 --- a/src/graphQLClientServer.js +++ b/src/graphQLClientServer.ts @@ -1,5 +1,6 @@ import mock, { proxy } from 'xhr-mock'; import handleRequestFactory from './handleRequest'; +import type { Data } from './types'; /** * Starts a GraphQL Server in your browser: intercepts every call to http://localhost:3000/graphql @@ -40,7 +41,7 @@ import handleRequestFactory from './handleRequest'; * GraphQLClientServer(data); * GraphQLClientServer(data, 'http://localhost:8080/api/graphql'); */ -export default function ({ data, url }) { +export default function ({ data, url }: { data: Data; url: string }) { const handleRequest = handleRequestFactory(data); return { @@ -62,7 +63,7 @@ export default function ({ data, url }) { resolve(res); }); - }) + }), ); // Ensure all other requests are handled by the default XmlHttpRequest diff --git a/src/graphiqlHandler.js b/src/graphiqlHandler.ts similarity index 92% rename from src/graphiqlHandler.js rename to src/graphiqlHandler.ts index fc59751..320e4fb 100644 --- a/src/graphiqlHandler.js +++ b/src/graphiqlHandler.ts @@ -1,15 +1,17 @@ -export const graphiqlHandler = (req, res) => { +import type { Handler } from 'express'; + +export const graphiqlHandler: Handler = (_, res) => { res.writeHead(200, undefined, { 'Content-Type': 'text/html; charset=utf-8', }); return res.end( getGraphiqlHtml({ endpoint: '/', - }) + }), ); }; -const getGraphiqlHtml = ({ endpoint }) => ` +const getGraphiqlHtml = ({ endpoint }: { endpoint: string }) => `