Skip to content
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

create new graphql package #4688

Merged
merged 6 commits into from
Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/five-gifts-lie.md
@@ -0,0 +1,5 @@
---
'@graphql-tools/graphql': patch
---

initial release
20 changes: 20 additions & 0 deletions .eslintrc.json
Expand Up @@ -47,6 +47,26 @@
"@typescript-eslint/no-unused-vars": "off",
"import/no-extraneous-dependencies": "off"
}
},
{
"files": ["packages/graphql/**"],
"env": {
"jest": true
},
"rules": {
"unicorn/filename-case": "off", // we keep the same file names as GraphQL.js
// TODO: Enable us incrementally
"no-use-before-define": "off",
"@typescript-eslint/prefer-as-const": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-inferrable-types": "off",
"unicorn/no-lonely-if": "off",
"@typescript-eslint/no-unused-vars": "off",
"prefer-rest-params": "off",
"no-throw-literal": "off",
"promise/param-names": "off",
"eqeqeq": "off"
}
Comment on lines +58 to +69
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry @B2o5T I will improve these in future PRs :)

}
],
"ignorePatterns": [
Expand Down
3 changes: 3 additions & 0 deletions packages/graphql/README.md
@@ -0,0 +1,3 @@
## `@graphql-tools/graphql`

Fork of GraphQL.js
65 changes: 65 additions & 0 deletions packages/graphql/package.json
@@ -0,0 +1,65 @@
{
"name": "@graphql-tools/graphql",
"version": "0.0.0",
"author": "Saihajpreet Singh <saihajpreet.singh@gmail.com>",
"license": "MIT",
"sideEffects": false,
"repository": {
"type": "git",
"url": "https://github.com/ardatan/graphql-tools.git",
"directory": "packages/graphql"
},
"keywords": [
"gql",
"graphql",
"typescript"
],
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"exports": {
".": {
"require": {
"types": "./dist/typings/index.d.cts",
"default": "./dist/cjs/index.js"
},
"import": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/esm/index.js"
},
"default": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/esm/index.js"
}
},
"./*": {
"require": {
"types": "./dist/typings/*.d.cts",
"default": "./dist/cjs/*.js"
},
"import": {
"types": "./dist/typings/*.d.ts",
"default": "./dist/esm/*.js"
},
"default": {
"types": "./dist/typings/*.d.ts",
"default": "./dist/esm/*.js"
}
},
"./package.json": "./package.json"
},
"typings": "dist/typings/index.d.ts",
"typescript": {
"definition": "dist/typings/index.d.ts"
},
"devDependencies": {
"typescript": "4.7.4"
},
"buildOptions": {
"input": "./src/index.ts"
},
"publishConfig": {
"directory": "dist",
"access": "public"
},
"type": "module"
}
102 changes: 102 additions & 0 deletions packages/graphql/src/__testUtils__/__tests__/dedent-test.ts
@@ -0,0 +1,102 @@
import { dedent, dedentString } from '../dedent.js';

describe('dedentString', () => {
it('removes indentation in typical usage', () => {
const output = dedentString(`
type Query {
me: User
}

type User {
id: ID
name: String
}
`);
expect(output).toEqual(
['type Query {', ' me: User', '}', '', 'type User {', ' id: ID', ' name: String', '}'].join('\n')
);
});

it('removes only the first level of indentation', () => {
const output = dedentString(`
first
second
third
fourth
`);
expect(output).toEqual(['first', ' second', ' third', ' fourth'].join('\n'));
});

it('does not escape special characters', () => {
const output = dedentString(`
type Root {
field(arg: String = "wi\th de\fault"): String
}
`);
expect(output).toEqual(['type Root {', ' field(arg: String = "wi\th de\fault"): String', '}'].join('\n'));
});

it('also removes indentation using tabs', () => {
const output = dedentString(`
\t\t type Query {
\t\t me: User
\t\t }
`);
expect(output).toEqual(['type Query {', ' me: User', '}'].join('\n'));
});

it('removes leading and trailing newlines', () => {
const output = dedentString(`


type Query {
me: User
}


`);
expect(output).toEqual(['type Query {', ' me: User', '}'].join('\n'));
});

it('removes all trailing spaces and tabs', () => {
const output = dedentString(`
type Query {
me: User
}
\t\t \t `);
expect(output).toEqual(['type Query {', ' me: User', '}'].join('\n'));
});

it('works on text without leading newline', () => {
const output = dedentString(` type Query {
me: User
}
`);
expect(output).toEqual(['type Query {', ' me: User', '}'].join('\n'));
});
});

describe('dedent', () => {
it('removes indentation in typical usage', () => {
const output = dedent`
type Query {
me: User
}
`;
expect(output).toEqual(['type Query {', ' me: User', '}'].join('\n'));
});

it('supports expression interpolation', () => {
const name = 'John';
const surname = 'Doe';
const output = dedent`
{
"me": {
"name": "${name}",
"surname": "${surname}"
}
}
`;
expect(output).toEqual(['{', ' "me": {', ' "name": "John",', ' "surname": "Doe"', ' }', '}'].join('\n'));
});
});
@@ -0,0 +1,38 @@
import { genFuzzStrings } from '../genFuzzStrings.js';

function expectFuzzStrings(options: { allowedChars: ReadonlyArray<string>; maxLength: number }) {
return expect([...genFuzzStrings(options)]);
}

describe('genFuzzStrings', () => {
it('always provide empty string', () => {
expectFuzzStrings({ allowedChars: [], maxLength: 0 }).toEqual(['']);
expectFuzzStrings({ allowedChars: [], maxLength: 1 }).toEqual(['']);
expectFuzzStrings({ allowedChars: ['a'], maxLength: 0 }).toEqual(['']);
});

it('generate strings with single character', () => {
expectFuzzStrings({ allowedChars: ['a'], maxLength: 1 }).toEqual(['', 'a']);

expectFuzzStrings({
allowedChars: ['a', 'b', 'c'],
maxLength: 1,
}).toEqual(['', 'a', 'b', 'c']);
});

it('generate strings with multiple character', () => {
expectFuzzStrings({ allowedChars: ['a'], maxLength: 2 }).toEqual(['', 'a', 'aa']);

expectFuzzStrings({
allowedChars: ['a', 'b', 'c'],
maxLength: 2,
}).toEqual(['', 'a', 'b', 'c', 'aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc']);
});

it('generate strings longer than possible number of characters', () => {
expectFuzzStrings({
allowedChars: ['a', 'b'],
maxLength: 3,
}).toEqual(['', 'a', 'b', 'aa', 'ab', 'ba', 'bb', 'aaa', 'aab', 'aba', 'abb', 'baa', 'bab', 'bba', 'bbb']);
});
});
16 changes: 16 additions & 0 deletions packages/graphql/src/__testUtils__/__tests__/inspectStr-test.ts
@@ -0,0 +1,16 @@
import { inspectStr } from '../inspectStr.js';

describe('inspectStr', () => {
it('handles null and undefined values', () => {
expect(inspectStr(null)).toEqual('null');
expect(inspectStr(undefined)).toEqual('null');
});

it('correctly print various strings', () => {
expect(inspectStr('')).toEqual('``');
expect(inspectStr('a')).toEqual('`a`');
expect(inspectStr('"')).toEqual('`"`');
expect(inspectStr("'")).toEqual("`'`");
expect(inspectStr('\\"')).toEqual('`\\"`');
});
});
@@ -0,0 +1,18 @@
import { resolveOnNextTick } from '../resolveOnNextTick.js';

describe('resolveOnNextTick', () => {
it('resolves promise on the next tick', async () => {
const output = [];

const promise1 = resolveOnNextTick().then(() => {
output.push('second');
});
const promise2 = resolveOnNextTick().then(() => {
output.push('third');
});
output.push('first');

await Promise.all([promise1, promise2]);
expect(output).toEqual(['first', 'second', 'third']);
});
});
38 changes: 38 additions & 0 deletions packages/graphql/src/__testUtils__/dedent.ts
@@ -0,0 +1,38 @@
export function dedentString(string: string): string {
const trimmedStr = string
.replace(/^\n*/m, '') // remove leading newline
.replace(/[ \t\n]*$/, ''); // remove trailing spaces and tabs

// fixes indentation by removing leading spaces and tabs from each line
let indent = '';
for (const char of trimmedStr) {
if (char !== ' ' && char !== '\t') {
break;
}
indent += char;
}

return trimmedStr.replace(RegExp('^' + indent, 'mg'), ''); // remove indent
}

/**
* An ES6 string tag that fixes indentation and also trims string.
*
* Example usage:
* ```ts
* const str = dedent`
* {
* test
* }
* `;
* str === "{\n test\n}";
* ```
*/
export function dedent(strings: ReadonlyArray<string>, ...values: ReadonlyArray<string>): string {
let str = strings[0];

for (let i = 1; i < strings.length; ++i) {
str += values[i - 1] + strings[i]; // interpolation
}
return dedentString(str);
}
51 changes: 51 additions & 0 deletions packages/graphql/src/__testUtils__/expectJSON.ts
@@ -0,0 +1,51 @@
import { isObjectLike } from '../jsutils/isObjectLike.js';
import { mapValue } from '../jsutils/mapValue.js';

/**
* Deeply transforms an arbitrary value to a JSON-safe value by calling toJSON
* on any nested value which defines it.
*/
function toJSONDeep(value: unknown): unknown {
if (!isObjectLike(value)) {
return value;
}

// @ts-expect-error: toJSON is not defined on all objects
if (typeof value.toJSON === 'function') {
// @ts-expect-error: toJSON is not defined on all objects
return value.toJSON();
}

if (Array.isArray(value)) {
return value.map(toJSONDeep);
}

return mapValue(value, toJSONDeep);
}

export function expectJSON(actual: unknown) {
const actualJSON = toJSONDeep(actual);

return {
toDeepEqual(expected: unknown) {
const expectedJSON = toJSONDeep(expected);
expect(actualJSON).toMatchObject(expectedJSON as any);
},
toDeepNestedProperty(path: string, expected: unknown) {
const expectedJSON = toJSONDeep(expected);
expect(actualJSON).toHaveProperty(path, expectedJSON);
},
};
}

export function expectToThrowJSON(fn: () => unknown) {
function mapException(): unknown {
try {
return fn();
} catch (error) {
return error;
}
}

return expect(mapException());
}