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

Add fp export #564

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .attw.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"includeEntrypoints": [
"array",
"compat",
"fp",
"function",
"math",
"object",
Expand Down
8 changes: 8 additions & 0 deletions .scripts/docs/generate-docs.mts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ async function run() {
);

await renderDocs(docsPaths, compatItems, { compat: true });

const fpItems = differenceWith(
toDocumentationItems(await doc(`file:${path.join(basePath, 'fp', 'index.ts')}`)),
items,
(x, y) => x.item.name === y.item.name
);

await renderDocs(docsPaths, fpItems, { fp: true });
}

async function renderDocs(docsPaths: DocumentationPaths, items: DocumentationItems, options: RenderOptions = {}) {
Expand Down
24 changes: 17 additions & 7 deletions .scripts/docs/operations/render/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { RenderOptions } from './types.ts';
import { DocumentationItem } from '../../types/DocumentationItem.ts';

export function render(item: DocumentationItem, options: RenderOptions = {}) {
return [title(item.name), compatNotice(options), item.description, signature(item), examples(item)]
return [title(item.name), getNotice(options), item.description, signature(item), examples(item)]
.filter(x => x != null)
.join('\n\n');
}
Expand All @@ -11,18 +11,28 @@ function title(name: string) {
return `# ${name}`;
}

function compatNotice(options: RenderOptions) {
if (!options.compat) {
return null;
}

return `
function getNotice(options: RenderOptions) {
if (options.compat) {
return `
::: info
This function is only available in \`es-toolkit/compat\` for compatibility reasons. It either has alternative native JavaScript APIs or isn’t fully optimized yet.

When imported from \`es-toolkit/compat\`, it behaves exactly like lodash and provides the same functionalities, as detailed [here](../../../compatibility.md).
:::
`.trim();
}

if (options.fp) {
return `
::: info
This function can only be imported from \`es-toolkit/fp\`, which supports writing code in a functional programming style.

When import code from \`es-toolkit/fp\`, you can use the pipe syntax or functions that automatically curry based on the number of input arguments.
:::
`.trim();
}

return null;
}

function signature(item: DocumentationItem) {
Expand Down
24 changes: 17 additions & 7 deletions .scripts/docs/operations/render/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { RenderOptions } from './types.ts';
import { DocumentationItem } from '../../types/DocumentationItem.ts';

export function render(item: DocumentationItem, options: RenderOptions = {}) {
return [title(item.name), compatNotice(options), item.description, signature(item), examples(item)]
return [title(item.name), getNotice(options), item.description, signature(item), examples(item)]
.filter(x => x != null)
.join('\n\n');
}
Expand All @@ -11,18 +11,28 @@ function title(name: string) {
return `# ${name}`;
}

function compatNotice(options: RenderOptions) {
if (!options.compat) {
return null;
}

return `
function getNotice(options: RenderOptions) {
if (options.compat) {
return `
::: info
この関数は互換性のために \`es-toolkit/compat\` からのみインポートできます。代替可能なネイティブ JavaScript API があるか、まだ十分に最適化されていないためです。

\`es-toolkit/compat\` からこの関数をインポートすると、[lodash と完全に同じように動作](../../../compatibility.md)します。
:::
`.trim();
}

if (options.fp) {
return `
::: info
この関数は関数型プログラミングスタイルのコードを書くために \`es-toolkit/fp\` からのみインポートできます。

\`es-toolkit/fp\` から関数をインポートすると、パイプ文法を使用したり、引数の数に応じて自動的に curry 化される関数を使用することができます。
:::
`.trim();
}

return null;
}

function signature(item: DocumentationItem) {
Expand Down
24 changes: 17 additions & 7 deletions .scripts/docs/operations/render/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { RenderOptions } from './types.ts';
import { DocumentationItem } from '../../types/DocumentationItem.ts';

export function render(item: DocumentationItem, options: RenderOptions = {}) {
return [title(item.name), compatNotice(options), item.description, signature(item), examples(item)]
return [title(item.name), getNotice(options), item.description, signature(item), examples(item)]
.filter(x => x != null)
.join('\n\n');
}
Expand All @@ -11,18 +11,28 @@ function title(name: string) {
return `# ${name}`;
}

function compatNotice(options: RenderOptions) {
if (!options.compat) {
return null;
}

return `
function getNotice(options: RenderOptions) {
if (options.compat) {
return `
::: info
이 함수는 호환성을 위한 \`es-toolkit/compat\` 에서만 가져올 수 있어요. 대체할 수 있는 네이티브 JavaScript API가 있거나, 아직 충분히 최적화되지 않았기 때문이에요.

\`es-toolkit/compat\`에서 이 함수를 가져오면, [lodash와 완전히 똑같이 동작](../../../compatibility.md)해요.
:::
`.trim();
}

if (options.fp) {
return `
::: info
이 함수는 함수형 프로그래밍 방식의 코드 작성을 지원하기 위한 \`es-toolkit/fp\` 에서만 가져올 수 있어요.

\`es-toolkit/fp\`에서 함수를 가져오면 pipe 문법을 사용하거나 인자 입력 갯수에 따라 자동으로 커링되는 함수를 사용할 수 있어요.
:::
`.trim();
}

return null;
}

function signature(item: DocumentationItem) {
Expand Down
1 change: 1 addition & 0 deletions .scripts/docs/operations/render/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export interface RenderOptions {
compat?: boolean;
fp?: boolean;
}
24 changes: 17 additions & 7 deletions .scripts/docs/operations/render/zh_hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { RenderOptions } from './types.ts';
import { DocumentationItem } from '../../types/DocumentationItem.ts';

export function render(item: DocumentationItem, options: RenderOptions = {}) {
return [title(item.name), compatNotice(options), item.description, signature(item), examples(item)]
return [title(item.name), getNotice(options), item.description, signature(item), examples(item)]
.filter(x => x != null)
.join('\n\n');
}
Expand All @@ -11,18 +11,28 @@ function title(name: string) {
return `# ${name}`;
}

function compatNotice(options: RenderOptions) {
if (!options.compat) {
return null;
}

return `
function getNotice(options: RenderOptions) {
if (options.compat) {
return `
::: info
出于兼容性原因,此函数仅在 \`es-toolkit/compat\` 中提供。它可能具有替代的原生 JavaScript API,或者尚未完全优化。

从 \`es-toolkit/compat\` 导入时,它的行为与 lodash 完全一致,并提供相同的功能,详情请见 [这里](../../../compatibility.md)。
:::
`.trim();
}

if (options.fp) {
return `
::: info
这个函数只能从 \`es-toolkit/fp\` 导入,以支持函数式编程风格的代码编写。

从 \`es-toolkit/fp\` 导入函数后,可以使用管道语法或根据输入参数数量自动 curry 化的函数。
:::
`.trim();
}

return null;
}

function signature(item: DocumentationItem) {
Expand Down
46 changes: 46 additions & 0 deletions .scripts/fp/_internal/getter/functionDeclaration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { CommentKind } from 'ast-types/gen/kinds';
import {
FunctionDeclaration,
Identifier,
JSCodeshift,
TSTypeAnnotation,
TSTypeParameterDeclaration,
TypeParameterDeclaration,
} from 'jscodeshift';

export function getFunctionDeclaration(
{
functionName,
typeParameters,
params,
returnType,
}: {
functionName: string;
typeParameters: TypeParameterDeclaration | TSTypeParameterDeclaration | null | undefined;
params: {
name: string[];
type: TSTypeAnnotation[];
};
returnType: TSTypeAnnotation;
},
j: JSCodeshift
) {
const newFunctionDeclaration = j.template.statement([
`
export function ${functionName}(${params.name.join(', ')});\n\n
`,
]) as {
comments?: CommentKind[];
declaration: Omit<FunctionDeclaration, 'params'> & {
params: Identifier[];
};
};

newFunctionDeclaration.declaration.typeParameters = typeParameters;
params.type.forEach((type, idx) => {
newFunctionDeclaration.declaration.params[idx].typeAnnotation = type;
});
newFunctionDeclaration.declaration.returnType = returnType;

return newFunctionDeclaration;
}
8 changes: 8 additions & 0 deletions .scripts/fp/_internal/getter/typedParam.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { JSCodeshift } from 'jscodeshift';
import { Param } from '../types';

export function getTypedParam({ name, type }: Param, j: JSCodeshift) {
const param = j.identifier(name);
param.typeAnnotation = j.tsTypeAnnotation(type);
return param;
}
6 changes: 6 additions & 0 deletions .scripts/fp/_internal/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { TSTypeKind } from 'ast-types/gen/kinds';

export type Param = {
name: string;
type: TSTypeKind;
};
15 changes: 15 additions & 0 deletions .scripts/fp/_internal/validator/functionDeclaration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Declaration, FunctionDeclaration, Identifier } from 'jscodeshift';
import { namedTypes as n } from 'ast-types';

export function isValidFunctionDeclaration(functionDeclaration: Declaration | null): functionDeclaration is Omit<
FunctionDeclaration,
'id'
> & {
id: Identifier;
} {
return (
n.FunctionDeclaration.check(functionDeclaration) &&
functionDeclaration.id != null &&
n.TSTypeAnnotation.check(functionDeclaration.returnType)
);
}
13 changes: 13 additions & 0 deletions .scripts/fp/_internal/validator/params.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Identifier, Pattern, TSTypeAnnotation } from 'jscodeshift';
import { namedTypes as n } from 'ast-types';

export function isValidParams(
params: Pattern[]
): params is (Omit<Identifier, 'typeAnnotation'> & { typeAnnotation: TSTypeAnnotation })[] {
return params.every(
param =>
n.Identifier.check(param) &&
n.TSTypeAnnotation.check(param.typeAnnotation) &&
!n.TSTypeAnnotation.check(param.typeAnnotation.typeAnnotation)
);
}
9 changes: 9 additions & 0 deletions .scripts/fp/create-fp-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FUNC=$1

find ./src -name "$1.ts" -maxdepth 2 -exec sh -c 'mkdir -p "./src/fp/$(dirname "{}" | sed "s|^./src/||")" && cp "{}" "./src/fp/$(dirname "{}" | sed "s|^./src/||")/"' \;
find ./src -name "$1.spec.ts" -maxdepth 2 -exec sh -c 'mkdir -p "./src/fp/$(dirname "{}" | sed "s|^./src/||")" && cp "{}" "./src/fp/$(dirname "{}" | sed "s|^./src/||")/"' \;
FP_FILENAME=$(find ./src/fp -name "$1.ts")
FP_SPEC_FILENAME=$(find ./src/fp -name "$1.spec.ts")
yarn jscodeshift -t ./.scripts/fp/toPipable.ts $FP_FILENAME
yarn jscodeshift -t ./.scripts/fp/toPipableSpec.ts $FP_SPEC_FILENAME
yarn prettier --write $FP_FILENAME
Loading