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

chore: adding pathgen instead of implementing on our own #35

Merged
merged 5 commits into from
Jan 5, 2025
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 46 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,76 +67,62 @@ output:
/* tslint:disable */
export type ILocaleKeys = {
common: {
loggedIn: {
message: (data: Record<'username', unknown>) => string,
},
},
readingWarning: (data: Record<'reader' | 'writer', unknown>) => string,
};
loggedIn: {
/* common.loggedIn.message */
/* Hey, {username}, you have successfully logged in! */
message: (data: Record<'username', unknown>) => string;
};
};
/* readingWarning */
/* {reader} reads message from {writer} */
readingWarning: (data: Record<'reader' | 'writer', unknown>) => string;
};
import { pathgen } from 'object-path-generator';

const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R,
prevKeys = ''
): unknown =>
new Proxy((...args: unknown[]) => t(prevKeys, ...args), {
get: (_, key: string): unknown => {
let nextKey = prevKeys;

if (key !== '$value') {
nextKey = prevKeys ? [prevKeys, key].join('.') : key;
}

return createProxyImpl(t, nextKey);
},
});
t = (...[k]: unknown[]) => k as R
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
) =>
pathgen<R>(undefined, (path, ...options) => {
const finalPath = path.split('.$value')[0];
return t(finalPath, ...options);
}) as unknown;

export function LocaleKeys<R extends string>(t: (...args: unknown[]) => R) {
return createProxyImpl(t) as ILocaleKeys;
return createProxyImpl(t) as ILocaleKeys;
}

```

output with React Hook:
```tsx
/* eslint-disable */
/* tslint:disable */
import React from 'react';
```

export type ILocaleKeys = {
common: {
loggedIn: {
message: (data: Record<'username', unknown>) => string,
},
},
readingWarning: (data: Record<'reader' | 'writer', unknown>) => string,
};
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R,
prevKeys = ''
): unknown =>
new Proxy((...args: unknown[]) => t(prevKeys, ...args), {
get: (_, key: string): unknown => {
let nextKey = prevKeys;

if (key !== '$value') {
nextKey = prevKeys ? [prevKeys, key].join('.') : key;
}

return createProxyImpl(t, nextKey);
},
});
### **React Support**

export function LocaleKeys<R extends string>(t: (...args: unknown[]) => R) {
return createProxyImpl(t) as ILocaleKeys;
}
Enable React integration by turning on the `--reactHook` flag or setting it in the configuration file.

const LocaleKeysContext = React.createContext({} as ILocaleKeys);
export const LocaleKeysProvider: React.FC<{ translateFn?: (...args: unknown[]) => string; localeKeys?: ILocaleKeys; children?: React.ReactNode }> = ({ translateFn, localeKeys, children }) => {
if (!translateFn && !localeKeys) { throw new Error('Either translateFn or localeKeys must be provided') }
const value = (typeof translateFn === 'function' ? LocaleKeys(translateFn) : localeKeys) as ILocaleKeys
return <LocaleKeysContext.Provider value={value}>{children}</LocaleKeysContext.Provider>;
};
export const useLocaleKeys = () => React.useContext(LocaleKeysContext);
#### **Usage Example**

```tsx
import { LocaleKeysProvider, useLocaleKeys } from './generated/localeKeys';

const App = () => {
const { t } = useI18n(); // Your translation function

return (
<LocaleKeysProvider translateFn={t}>
<ChildComponent />
</LocaleKeysProvider>
);
};

const ChildComponent = () => {
const localeKeys = useLocaleKeys();

return (
<div>
{localeKeys.common.loggedIn.message({ username: 'John' })}
</div>
);
};
```

## Configuration file
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@
"typecheck": "tsc --noEmit",
"pretest": "yarn run clean-generated && yarn run generate-for-type-tests && yarn run lint && yarn run typecheck && yarn run build",
"test": "jest -i",
"build": "tsc -p tsconfig.build.json",
"build": "tsc -p tsconfig.build.json && yarn copy-templates",
"copy-templates": "cpx 'src/**/*.template.*' dist/",
"generate-readme": "ts-node scripts/generateReadme.ts"
},
"dependencies": {
"@types/flat": "^5.0.2",
"child-process-promise": "^2.2.1",
"cosmiconfig": "^7.0.1",
"cpx": "^1.5.0",
"flat": "^5.0.2",
"format-message-parse": "^6.2.4",
"handlebars": "^4.7.7",
"object-path-generator": "^1.0.1",
"ts-essentials": "^8.1.0",
"ts-morph": "^12.0.0",
"ts-node": "^10.2.1",
Expand Down
23 changes: 9 additions & 14 deletions src/proxyEngine/proxyEngine.template.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
const __proxyImplName__ = <R extends string>(
t = (...[k]: unknown[]) => k as R,
prevKeys = ''
): unknown =>
new Proxy((...args: unknown[]) => t(prevKeys, ...args), {
get: (_, key: string): unknown => {
let nextKey = prevKeys;

if (key !== '__ownValueAlias__') {
nextKey = prevKeys ? [prevKeys, key].join('.') : key;
}
import { pathgen } from 'object-path-generator';

return __proxyImplName__(t, nextKey);
},
});
const __proxyImplName__ = <R extends string>(
t = (...[k]: unknown[]) => k as R
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
) =>
pathgen<R>(undefined, (path: string, ...options: any[]) => {
const finalPath = path.split('.__ownValueAlias__')[0];
return t(finalPath, ...options);
}) as unknown;
138 changes: 54 additions & 84 deletions tests/__snapshots__/generator.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,16 @@ export type ILocaleKeys = {
};
};
};
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R,
prevKeys = ''
): unknown =>
new Proxy((...args: unknown[]) => t(prevKeys, ...args), {
get: (_, key: string): unknown => {
let nextKey = prevKeys;

if (key !== '$value') {
nextKey = prevKeys ? [prevKeys, key].join('.') : key;
}
import { pathgen } from 'object-path-generator';

return createProxyImpl(t, nextKey);
},
});
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
) =>
pathgen<R>(undefined, (path: string, ...options: any[]) => {
const finalPath = path.split('.$value')[0];
return t(finalPath, ...options);
}) as unknown;

export function LocaleKeys<R extends string>(t: (...args: unknown[]) => R) {
return createProxyImpl(t) as ILocaleKeys;
Expand Down Expand Up @@ -76,21 +71,16 @@ export type ILocaleKeys = {
};
};
};
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R,
prevKeys = ''
): unknown =>
new Proxy((...args: unknown[]) => t(prevKeys, ...args), {
get: (_, key: string): unknown => {
let nextKey = prevKeys;
import { pathgen } from 'object-path-generator';

if (key !== '$value') {
nextKey = prevKeys ? [prevKeys, key].join('.') : key;
}

return createProxyImpl(t, nextKey);
},
});
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
) =>
pathgen<R>(undefined, (path: string, ...options: any[]) => {
const finalPath = path.split('.$value')[0];
return t(finalPath, ...options);
}) as unknown;

export function LocaleKeys<R extends string>(t: (...args: unknown[]) => R) {
return createProxyImpl(t) as ILocaleKeys;
Expand All @@ -113,21 +103,16 @@ export type ILocaleKeys = {
};
};
};
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R,
prevKeys = ''
): unknown =>
new Proxy((...args: unknown[]) => t(prevKeys, ...args), {
get: (_, key: string): unknown => {
let nextKey = prevKeys;

if (key !== '$value') {
nextKey = prevKeys ? [prevKeys, key].join('.') : key;
}
import { pathgen } from 'object-path-generator';

return createProxyImpl(t, nextKey);
},
});
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
) =>
pathgen<R>(undefined, (path: string, ...options: any[]) => {
const finalPath = path.split('.$value')[0];
return t(finalPath, ...options);
}) as unknown;

export function LocaleKeys<R extends string>(t: (...args: unknown[]) => R) {
return createProxyImpl(t) as ILocaleKeys;
Expand All @@ -150,21 +135,16 @@ export type ILocaleKeys = {
/* {reader} reads message from {writer} */
readingWarning: (data: Record<'reader' | 'writer', unknown>) => string;
};
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R,
prevKeys = ''
): unknown =>
new Proxy((...args: unknown[]) => t(prevKeys, ...args), {
get: (_, key: string): unknown => {
let nextKey = prevKeys;
import { pathgen } from 'object-path-generator';

if (key !== '$value') {
nextKey = prevKeys ? [prevKeys, key].join('.') : key;
}

return createProxyImpl(t, nextKey);
},
});
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
) =>
pathgen<R>(undefined, (path: string, ...options: any[]) => {
const finalPath = path.split('.$value')[0];
return t(finalPath, ...options);
}) as unknown;

export function LocaleKeys<R extends string>(t: (...args: unknown[]) => R) {
return createProxyImpl(t) as ILocaleKeys;
Expand All @@ -189,21 +169,16 @@ export type ILocaleKeys = {
};
};
};
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R,
prevKeys = ''
): unknown =>
new Proxy((...args: unknown[]) => t(prevKeys, ...args), {
get: (_, key: string): unknown => {
let nextKey = prevKeys;

if (key !== '$value') {
nextKey = prevKeys ? [prevKeys, key].join('.') : key;
}
import { pathgen } from 'object-path-generator';

return createProxyImpl(t, nextKey);
},
});
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
) =>
pathgen<R>(undefined, (path: string, ...options: any[]) => {
const finalPath = path.split('.$value')[0];
return t(finalPath, ...options);
}) as unknown;

export function LocaleKeys<R extends string>(t: (...args: unknown[]) => R) {
return createProxyImpl(t) as ILocaleKeys;
Expand All @@ -228,21 +203,16 @@ export type ILocaleKeys = {
};
};
};
import { pathgen } from 'object-path-generator';

const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R,
prevKeys = ''
): unknown =>
new Proxy((...args: unknown[]) => t(prevKeys, ...args), {
get: (_, key: string): unknown => {
let nextKey = prevKeys;

if (key !== '$value') {
nextKey = prevKeys ? [prevKeys, key].join('.') : key;
}

return createProxyImpl(t, nextKey);
},
});
t = (...[k]: unknown[]) => k as R
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
) =>
pathgen<R>(undefined, (path: string, ...options: any[]) => {
const finalPath = path.split('.$value')[0];
return t(finalPath, ...options);
}) as unknown;

export function LocaleKeys<R extends string>(t: (...args: unknown[]) => R) {
return createProxyImpl(t) as ILocaleKeys;
Expand Down
26 changes: 10 additions & 16 deletions tests/__snapshots__/reactBindings.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
exports[`react file (snapshot) 1`] = `
"/* eslint-disable */
/* tslint:disable */
import React from 'react';

export type ILocaleKeys = {
common: {
loggedIn: {
Expand All @@ -17,21 +15,17 @@ export type ILocaleKeys = {
/* {{reader}} reads message from {{writer}} */
readingWarning: (data: Record<'reader' | 'writer', unknown>) => string;
};
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R,
prevKeys = ''
): unknown =>
new Proxy((...args: unknown[]) => t(prevKeys, ...args), {
get: (_, key: string): unknown => {
let nextKey = prevKeys;

if (key !== '$value') {
nextKey = prevKeys ? [prevKeys, key].join('.') : key;
}
import { pathgen } from 'object-path-generator';
import React from 'react';

return createProxyImpl(t, nextKey);
},
});
const createProxyImpl = <R extends string>(
t = (...[k]: unknown[]) => k as R
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
) =>
pathgen<R>(undefined, (path: string, ...options: any[]) => {
const finalPath = path.split('.$value')[0];
return t(finalPath, ...options);
}) as unknown;

export function LocaleKeys<R extends string>(t: (...args: unknown[]) => R) {
return createProxyImpl(t) as ILocaleKeys;
Expand Down
Loading
Loading