Skip to content

Commit d12f743

Browse files
committed
[WIP] [Breaking] Drop Flow type support in favor of TypeScript
1 parent 66eb26a commit d12f743

File tree

11 files changed

+2199
-3701
lines changed

11 files changed

+2199
-3701
lines changed

.babelrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"@babel/preset-env",
55
{
66
"targets": {
7-
"node": "10"
7+
"node": "22"
88
}
99
}
1010
],

__tests__/genType.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { getResourceTypeReference, getNewKeyTypeFromBatchKeySetType, getLoaderTypeKey } from '../src/genType';
2+
3+
it('getResourceTypeReference converts a resource path to a valid reference', () => {
4+
expect(getResourceTypeReference(null, ['foo', 'bar', 'baz'])).toBe(
5+
"ResourcesType['foo']['bar']['baz']",
6+
);
7+
});
8+
9+
it('getNewKeyTypeFromBatchKeySetType returns a newKey type with a valid value', () => {
10+
expect(
11+
getNewKeyTypeFromBatchKeySetType(
12+
'bKey',
13+
"ResourcesType['foo']['bar']['baz']",
14+
),
15+
).toBe(`Parameters<ResourcesType['foo']['bar']['baz']['bKey']['has']>[0]`);
16+
});
17+
18+
it('getLoaderTypeKey forces a nullable batchKey to be strictly non-nullable', () => {
19+
expect(
20+
getLoaderTypeKey(
21+
{
22+
isBatchResource: true,
23+
newKey: 'test_id',
24+
batchKey: 'test_ids',
25+
},
26+
['a', 'b'],
27+
),
28+
).toBe(`Exclude<Parameters<ResourcesType['a']['b']>[0], 'test_ids'> & { test_id: NonNullable<Parameters<ResourcesType['a']['b']>[0]['test_ids']>[0] }`);
29+
});

__tests__/genTypeFlow.test.js

Lines changed: 0 additions & 47 deletions
This file was deleted.

__tests__/implementation.test.js

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ import { getConfig } from '../src/config';
99

1010
const BABEL_CONFIG = {
1111
presets: [
12-
'@babel/preset-flow',
12+
'@babel/preset-typescript',
1313
[
1414
'@babel/preset-env',
1515
{
1616
modules: 'commonjs',
1717
},
1818
],
1919
],
20+
// Babel needs this dummy file name to determine it's a TypeScript file
21+
filename: 'file.ts',
2022
};
2123

2224
const RUNTIME_HELPERS = path.resolve(__dirname, '..', 'src', 'runtimeHelpers.ts');
@@ -45,7 +47,7 @@ expect.extend({
4547
async function createDataLoaders(config, cb) {
4648
await tmp.withFile(
4749
async ({ path }) => {
48-
const loadersCode = await babel.transformAsync(codegen(config, RUNTIME_HELPERS), BABEL_CONFIG);
50+
const loadersCode = await babel.transformAsync(await codegen(config, RUNTIME_HELPERS), BABEL_CONFIG);
4951
fs.writeFileSync(path, 'const regeneratorRuntime = require("regenerator-runtime");');
5052
fs.appendFileSync(path, loadersCode.code);
5153
// Import the generated code into memory :scream:
@@ -1608,3 +1610,49 @@ test('batch endpoint with propertyBatchKey with reorderResultsByKey handles resp
16081610
]);
16091611
});
16101612
});
1613+
1614+
test('embeds resource types', async () => {
1615+
// For the sake of coverage we pass in these test comments which will get interpolated in the generated code
1616+
// but otherwise we don't need to test them.
1617+
const config = {
1618+
resources: {
1619+
foo: {
1620+
isBatchResource: false,
1621+
docsLink: 'example.com/docs/foo',
1622+
},
1623+
},
1624+
typings: {
1625+
embedResourcesType: {
1626+
imports: '// test foo',
1627+
ResourcesType: '// test bar',
1628+
},
1629+
}
1630+
};
1631+
1632+
const resources = {
1633+
foo: jest
1634+
.fn()
1635+
.mockReturnValueOnce(
1636+
Promise.resolve({
1637+
message: 'knock knock',
1638+
message_suffix: '!',
1639+
}),
1640+
)
1641+
.mockReturnValueOnce(
1642+
Promise.resolve({
1643+
message: "who's there",
1644+
message_suffix: '?',
1645+
}),
1646+
),
1647+
};
1648+
1649+
await createDataLoaders(config, async (getLoaders) => {
1650+
const loaders = getLoaders(resources);
1651+
1652+
const results = await loaders.foo.loadMany([{ bar_id: 1 }, { bar_id: 2 }]);
1653+
expect(results).toEqual([
1654+
{ message: 'knock knock', message_suffix: '!' },
1655+
{ message: "who's there", message_suffix: '?' },
1656+
]);
1657+
});
1658+
});

jest.config.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ module.exports = {
22
collectCoverage: true,
33
coverageThreshold: {
44
global: {
5-
branches: 89,
6-
functions: 92,
7-
lines: 95,
8-
statements: 94,
5+
branches: 100,
6+
functions: 100,
7+
lines: 100,
8+
statements: 100,
99
},
1010
},
1111
coveragePathIgnorePatterns: ['<rootDir>/src/config.ts', '<rootDir>/__tests__/test-tmp-files'],

package.json

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
},
1717
"license": "MIT",
1818
"scripts": {
19-
"test": "jest",
19+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
2020
"build": "babel --verbose --extensions '.ts' src -d lib",
2121
"prepublishOnly": "make build",
2222
"typecheck": "tsc --project tsconfig.json"
@@ -25,34 +25,33 @@
2525
"dataloader-codegen": "./lib/index.js"
2626
},
2727
"devDependencies": {
28-
"@babel/cli": "^7.6.3",
29-
"@babel/core": "^7.6.4",
30-
"@babel/preset-flow": "^7.0.0",
31-
"@babel/preset-typescript": "^7.6.0",
32-
"@types/jest": "^25.1.2",
28+
"@babel/cli": "^7.27.2",
29+
"@babel/core": "^7.27.4",
30+
"@babel/preset-flow": "^7.27.1",
31+
"@babel/preset-typescript": "^7.27.1",
32+
"@types/jest": "^29.5.14",
3333
"@types/js-yaml": "^3.12.1",
34-
"@types/lodash": "^4.14.144",
35-
"@types/node": "^12.7.12",
34+
"@types/lodash": "^4.17.17",
35+
"@types/node": "^24.0.1",
3636
"@types/object-hash": "^1.3.0",
37-
"@types/prettier": "^1.18.3",
3837
"@types/yargs": "^13.0.3",
3938
"flow-bin": "^0.121.0",
4039
"flowgen": "^1.10.0",
41-
"jest": "^25.1.0",
40+
"jest": "^29.7.0",
4241
"regenerator-runtime": "^0.13.3",
4342
"tmp-promise": "^2.0.2",
44-
"typescript": "^3.7.0-beta"
43+
"typescript": "^5.8.3"
4544
},
4645
"dependencies": {
47-
"@babel/preset-env": "^7.6.3",
46+
"@babel/preset-env": "^7.27.2",
4847
"aggregate-error": "^3.0.1",
4948
"ajv": "^6.11.0",
5049
"dataloader": "^2.0.0",
5150
"ensure-error": "^2.0.0",
5251
"js-yaml": "^3.13.1",
53-
"lodash": "^4.17.15",
52+
"lodash": "^4.17.17",
5453
"object-hash": "^2.0.0",
55-
"prettier": "^1.19.1",
54+
"prettier": "^3.5.3",
5655
"yargs": "^14.2.0"
5756
},
5857
"files": [

src/codegen.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import _ from 'lodash';
22
import prettier from 'prettier';
33
import { GlobalConfig, getResourcePaths } from './config';
4-
import { getLoaderType, getLoadersTypeMap, getResourceTypings } from './genTypeFlow';
4+
import { getLoaderType, getLoadersTypeMap, getResourceTypings } from './genType';
55
import getLoaderImplementation from './implementation';
66

77
function getLoaders(config: object, paths: Array<Array<string>>, current: Array<string>) {
@@ -46,8 +46,6 @@ export default function codegen(
4646
const { printResourceTypeImports, printResourcesType } = getResourceTypings(config);
4747

4848
const output = `
49-
// @flow strict-local
50-
5149
/**
5250
* !!! THIS FILE IS AUTO-GENERATED. CHANGES MAY BE OVERWRITTEN !!!
5351
*/
@@ -82,21 +80,22 @@ export default function codegen(
8280
* ===============================
8381
*/
8482
85-
// https://github.com/facebook/flow/issues/7709#issuecomment-530501257
86-
type ExtractArg = <Arg, Ret>([Arg => Ret]) => Arg;
87-
type ExtractPromisedReturnValue<A> = <R>((...A) => Promise<R>) => R;
83+
type PromisedReturnType<F extends (...args: any) => Promise<any>> =
84+
F extends (...args: any) => Promise<infer R> ? R : never;
85+
86+
type Values<T> = T[keyof T];
8887
89-
export type DataLoaderCodegenOptions = {|
88+
export type DataLoaderCodegenOptions = {
9089
errorHandler?: (
91-
resourcePath: $ReadOnlyArray<string>,
92-
// $FlowFixMe: We don't know what type the resource might throw, so we have to type error to "any" :(
90+
resourcePath: ReadonlyArray<string>,
91+
// We don't know what type the resource might throw, so we have to type error to "any" :(
9392
error: any,
9493
) => Promise<Error>,
95-
resourceMiddleware?: {|
96-
before?: <T>(resourcePath: $ReadOnlyArray<string>, resourceArgs: T) => Promise<T>,
97-
after?: <T>(resourcePath: $ReadOnlyArray<string>, response: T) => Promise<T>,
98-
|};
99-
|};
94+
resourceMiddleware?: {
95+
before?: <T>(resourcePath: ReadonlyArray<string>, resourceArgs: T) => Promise<T>,
96+
after?: <T>(resourcePath: ReadonlyArray<string>, response: T) => Promise<T>,
97+
};
98+
};
10099
101100
/**
102101
* ===============================
@@ -117,5 +116,5 @@ export default function codegen(
117116
}
118117
`;
119118

120-
return prettier.format(output, { parser: 'babel' });
119+
return prettier.format(output, { parser: 'babel-ts' });
121120
}

0 commit comments

Comments
 (0)