diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9f3c0dfc..2410c799 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,11 +5,12 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: matrix: node-version: [12.x] + os: [windows-latest, ubuntu-latest] steps: - uses: actions/checkout@v2 diff --git a/package.json b/package.json index 13533546..8cdf4e3d 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "node-fetch": "2.6.1" }, "dependencies": { - "@himenon/path-oriented-data-structure": "0.1.0", + "@himenon/path-oriented-data-structure": "0.1.3", "@types/json-schema": "7.0.6", "ajv": "7.0.3", "dot-prop": "6.0.1", diff --git a/scripts/tools/copyPackageSet.ts b/scripts/tools/copyPackageSet.ts index 1a61072d..b50ac695 100644 --- a/scripts/tools/copyPackageSet.ts +++ b/scripts/tools/copyPackageSet.ts @@ -13,9 +13,9 @@ export const copyPackageSet = async (): Promise => { const libDir = "lib"; const publishPackageJson = path.join(libDir, "package.json"); pkg.private = undefined; - pkg.main = path.relative(libDir, pkg.main); - pkg.module = path.relative(libDir, pkg.module); - pkg.types = path.relative(libDir, pkg.types); + pkg.main = path.posix.relative(libDir, pkg.main); + pkg.module = path.posix.relative(libDir, pkg.module); + pkg.types = path.posix.relative(libDir, pkg.types); pkg.directories = undefined; pkg.files = undefined; fs.writeFileSync(publishPackageJson, JSON.stringify(pkg, null, 2), { diff --git a/src/CodeGenerator/factory/utils.ts b/src/CodeGenerator/factory/utils.ts index 176d38b2..02562295 100644 --- a/src/CodeGenerator/factory/utils.ts +++ b/src/CodeGenerator/factory/utils.ts @@ -14,7 +14,7 @@ export const escapeIdentiferText = (text: string): string => { }; export const generateComment = (comment: string, deprecated?: boolean): Comment => { - const splitComments = deprecated ? ["@deprecated"].concat(comment.split(EOL)) : comment.split(EOL); + const splitComments = deprecated ? ["@deprecated"].concat(comment.split(/\r?\n/)) : comment.split(/\r?\n/); const comments = splitComments.filter((comment, index) => { if (index === splitComments.length - 1 && comment === "") { return false; diff --git a/src/Converter/v3/TypeNodeContext.ts b/src/Converter/v3/TypeNodeContext.ts index a1aea381..48a833b6 100644 --- a/src/Converter/v3/TypeNodeContext.ts +++ b/src/Converter/v3/TypeNodeContext.ts @@ -16,8 +16,8 @@ export interface ReferencePathSet { const generatePath = (entryPoint: string, currentPoint: string, referencePath: string): ReferencePathSet => { const ext = Path.extname(currentPoint); // .yml const from = Path.relative(Path.dirname(entryPoint), currentPoint).replace(ext, ""); // components/schemas/A/B - const base = Path.dirname(from); - const result = Path.relative(base, referencePath); // remoteの場合? localの場合 referencePath.split("/") + const base = Path.dirname(from).replace(Path.sep, "/"); + const result = Path.posix.relative(base, referencePath); // remoteの場合? localの場合 referencePath.split("/") const pathArray = result.split("/"); return { pathArray, @@ -29,7 +29,7 @@ const calculateReferencePath = (store: Store.Type, base: string, pathArray: stri let names: string[] = []; let unresolvedPaths: string[] = []; pathArray.reduce((previous, lastPath, index) => { - const current = Path.join(previous, lastPath); + const current = Path.posix.join(previous, lastPath); // ディレクトリが深い場合は相対パスが`..`を繰り返す可能性があり、 // その場合はすでに登録されたnamesを削除する if (lastPath === ".." && names.length > 0) { diff --git a/src/Converter/v3/components/Reference.ts b/src/Converter/v3/components/Reference.ts index d98b0790..608bdc8e 100644 --- a/src/Converter/v3/components/Reference.ts +++ b/src/Converter/v3/components/Reference.ts @@ -100,7 +100,7 @@ export const generateLocalReference = (reference: OpenApi.Reference): LocalRefer return; } const name = reference.$ref.split(localReferencePattern)[1]; - const localPath = path.join(localReferenceComponents[localReferencePattern], name); + const localPath = path.posix.join(localReferenceComponents[localReferencePattern], name); if (!localPath.startsWith("components")) { throw new DevelopmentError(`localPath is not start "components":\n${localPath}`); } @@ -138,7 +138,7 @@ export const generate = (entryPoint: string, currentPoint: string, reference: const relativePathFromEntryPoint = path.relative(path.dirname(entryPoint), referencePoint); // components/hoge/fuga.yml const ext = path.extname(relativePathFromEntryPoint); // .yml - const pathArray: string[] = relativePathFromEntryPoint.replace(ext, "").split("/"); // ["components", "hoge", "fuga"] + const pathArray: string[] = relativePathFromEntryPoint.replace(ext, "").split(path.sep); // ["components", "hoge", "fuga"] const targetPath: string = pathArray.join("/"); // components/hoge/fuga const schemaName = pathArray[pathArray.length - 1]; // fuga const componentName = pathArray[0] === "components" ? pathArray[1] : ""; diff --git a/src/Converter/v3/components/Response.ts b/src/Converter/v3/components/Response.ts index 835b9d70..d4216cef 100644 --- a/src/Converter/v3/components/Response.ts +++ b/src/Converter/v3/components/Response.ts @@ -77,7 +77,7 @@ export const generateReferenceNamespace = ( kind: "namespace", name: nameWithStatusCode, }); - const headerNamespace = store.getStatement(path.join(responseReference.path, "Header"), "namespace"); + const headerNamespace = store.getStatement(path.posix.join(responseReference.path, "Header"), "namespace"); if (headerNamespace) { store.addStatement(`${basePath}/Header`, { kind: "namespace", diff --git a/src/Converter/v3/components/Responses.ts b/src/Converter/v3/components/Responses.ts index 64c920a7..bbdbb78f 100644 --- a/src/Converter/v3/components/Responses.ts +++ b/src/Converter/v3/components/Responses.ts @@ -41,7 +41,7 @@ export const generateNamespace = ( reference.referencePoint, store, factory, - path.dirname(reference.path), // referencePoint basename === namespace name + path.posix.dirname(reference.path), // referencePoint basename === namespace name reference.name, reference.data, context, @@ -94,7 +94,7 @@ export const generateNamespaceWithStatusCode = ( reference.referencePoint, store, factory, - path.dirname(reference.path), // referencePoint basename === namespace name + path.posix.dirname(reference.path), // referencePoint basename === namespace name reference.name, reference.data, context, @@ -157,7 +157,7 @@ export const generateInterfacesWithStatusCode = ( reference.referencePoint, store, factory, - path.dirname(reference.path), // referencePoint basename === namespace name + path.posix.dirname(reference.path), // referencePoint basename === namespace name reference.name, reference.data, context, diff --git a/src/Converter/v3/store/Store.ts b/src/Converter/v3/store/Store.ts index e1a92541..d3836299 100644 --- a/src/Converter/v3/store/Store.ts +++ b/src/Converter/v3/store/Store.ts @@ -1,4 +1,4 @@ -import { relative } from "path"; +import * as Path from "path"; import { Tree } from "@himenon/path-oriented-data-structure"; import Dot from "dot-prop"; @@ -87,11 +87,11 @@ export const create = (factory: Factory.Type, rootDocument: OpenApi.Document): T if (!path.startsWith("components")) { throw new UnSupportError(`componentsから始まっていません。path=${path}`); } - const targetPath = relative("components", path); + const targetPath = Path.posix.relative("components", path); operator.set(targetPath, Structure.createInstance(statement)); }, getStatement: (path: string, kind: T): Structure.DataStructure.GetChild | undefined => { - const targetPath = relative("components", path); + const targetPath = Path.posix.relative("components", path); return getChildByPaths(targetPath, kind); }, getRootStatements, diff --git a/src/DefaultCodeTemplate/ApiClientClass/MethodBody/__tests__/PathParameter-test.ts b/src/DefaultCodeTemplate/ApiClientClass/MethodBody/__tests__/PathParameter-test.ts index d28d5c00..0cd2ff8c 100644 --- a/src/DefaultCodeTemplate/ApiClientClass/MethodBody/__tests__/PathParameter-test.ts +++ b/src/DefaultCodeTemplate/ApiClientClass/MethodBody/__tests__/PathParameter-test.ts @@ -1,3 +1,5 @@ +import { EOL } from "os"; + import ts from "typescript"; import { Factory } from "../../../../CodeGenerator"; @@ -40,68 +42,68 @@ describe("PathParameter Test", () => { return getText(expression); }; test("generateUrlTemplateExpression", () => { - expect(generate("/{a}", [{ in: "path", name: "a", required: true }])).toBe("`/${params.parameter.a}`;\n"); - expect(generate("/{a}/", [{ in: "path", name: "a", required: true }])).toBe("`/${params.parameter.a}/`;\n"); - expect(generate("/a/{b}", [{ in: "path", name: "b", required: true }])).toBe("`/a/${params.parameter.b}`;\n"); - expect(generate("/a/{b}/", [{ in: "path", name: "b", required: true }])).toBe("`/a/${params.parameter.b}/`;\n"); - expect(generate("/a/{b}/c", [{ in: "path", name: "b", required: true }])).toBe("`/a/${params.parameter.b}/c`;\n"); - expect(generate("/a/{b}/c/", [{ in: "path", name: "b", required: true }])).toBe("`/a/${params.parameter.b}/c/`;\n"); - expect(generate("/a/b/{c}", [{ in: "path", name: "c", required: true }])).toBe("`/a/b/${params.parameter.c}`;\n"); - expect(generate("/a/b/{c}/", [{ in: "path", name: "c", required: true }])).toBe("`/a/b/${params.parameter.c}/`;\n"); + expect(generate("/{a}", [{ in: "path", name: "a", required: true }])).toBe("`/${params.parameter.a}`;" + EOL); + expect(generate("/{a}/", [{ in: "path", name: "a", required: true }])).toBe("`/${params.parameter.a}/`;" + EOL); + expect(generate("/a/{b}", [{ in: "path", name: "b", required: true }])).toBe("`/a/${params.parameter.b}`;" + EOL); + expect(generate("/a/{b}/", [{ in: "path", name: "b", required: true }])).toBe("`/a/${params.parameter.b}/`;" + EOL); + expect(generate("/a/{b}/c", [{ in: "path", name: "b", required: true }])).toBe("`/a/${params.parameter.b}/c`;" + EOL); + expect(generate("/a/{b}/c/", [{ in: "path", name: "b", required: true }])).toBe("`/a/${params.parameter.b}/c/`;" + EOL); + expect(generate("/a/b/{c}", [{ in: "path", name: "c", required: true }])).toBe("`/a/b/${params.parameter.c}`;" + EOL); + expect(generate("/a/b/{c}/", [{ in: "path", name: "c", required: true }])).toBe("`/a/b/${params.parameter.c}/`;" + EOL); expect( generate("/{a}/{b}", [ { in: "path", name: "a", required: true }, { in: "path", name: "b", required: true }, ]), - ).toBe("`/${params.parameter.a}/${params.parameter.b}`;\n"); + ).toBe("`/${params.parameter.a}/${params.parameter.b}`;" + EOL); expect( generate("/{a}/{b}/", [ { in: "path", name: "a", required: true }, { in: "path", name: "b", required: true }, ]), - ).toBe("`/${params.parameter.a}/${params.parameter.b}/`;\n"); + ).toBe("`/${params.parameter.a}/${params.parameter.b}/`;" + EOL); expect( generate("/{a}/{b}/c", [ { in: "path", name: "a", required: true }, { in: "path", name: "b", required: true }, ]), - ).toBe("`/${params.parameter.a}/${params.parameter.b}/c`;\n"); + ).toBe("`/${params.parameter.a}/${params.parameter.b}/c`;" + EOL); expect( generate("/{a}/{b}/c/", [ { in: "path", name: "a", required: true }, { in: "path", name: "b", required: true }, ]), - ).toBe("`/${params.parameter.a}/${params.parameter.b}/c/`;\n"); + ).toBe("`/${params.parameter.a}/${params.parameter.b}/c/`;" + EOL); expect( generate("/{a}/b/{c}", [ { in: "path", name: "a", required: true }, { in: "path", name: "c", required: true }, ]), - ).toBe("`/${params.parameter.a}/b/${params.parameter.c}`;\n"); + ).toBe("`/${params.parameter.a}/b/${params.parameter.c}`;" + EOL); expect( generate("/{a}/b/{c}/", [ { in: "path", name: "a", required: true }, { in: "path", name: "c", required: true }, ]), - ).toBe("`/${params.parameter.a}/b/${params.parameter.c}/`;\n"); + ).toBe("`/${params.parameter.a}/b/${params.parameter.c}/`;" + EOL); expect( generate("/a/{b}/{c}", [ { in: "path", name: "b", required: true }, { in: "path", name: "c", required: true }, ]), - ).toBe("`/a/${params.parameter.b}/${params.parameter.c}`;\n"); + ).toBe("`/a/${params.parameter.b}/${params.parameter.c}`;" + EOL); expect( generate("/a/{b}/{c}/", [ { in: "path", name: "b", required: true }, { in: "path", name: "c", required: true }, ]), - ).toBe("`/a/${params.parameter.b}/${params.parameter.c}/`;\n"); + ).toBe("`/a/${params.parameter.b}/${params.parameter.c}/`;" + EOL); expect( generate("/a/{b}...{c}/", [ { in: "path", name: "b", required: true }, { in: "path", name: "c", required: true }, ]), - ).toBe("`/a/${params.parameter.b}...${params.parameter.c}/`;\n"); + ).toBe("`/a/${params.parameter.b}...${params.parameter.c}/`;" + EOL); }); }); diff --git a/yarn.lock b/yarn.lock index 11aae788..9f90d747 100644 --- a/yarn.lock +++ b/yarn.lock @@ -633,10 +633,10 @@ unique-filename "^1.1.1" which "^1.3.1" -"@himenon/path-oriented-data-structure@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@himenon/path-oriented-data-structure/-/path-oriented-data-structure-0.1.0.tgz#b417a3cb46e3bbc409c4fc5216c42d924f2e7433" - integrity sha512-pU4wymQPvBbtPDyeVP8RekOUsQbUiztEae38BIPLFRSqOM68xCNcFzng71HhI2ZdD0kbt+zK1HgQKwB/nv8VkA== +"@himenon/path-oriented-data-structure@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@himenon/path-oriented-data-structure/-/path-oriented-data-structure-0.1.3.tgz#a9298afd0097e2f5e466a2f86318c887e82570ed" + integrity sha512-1QaIv/cFdpg5GkpG6pQgrYgDouRO7dzz3djiSKLgd2+GjqMG0TsVvUaAxtIo7Y6Hqdk/pL7u7U+cYf80ww9tcw== "@istanbuljs/load-nyc-config@^1.0.0": version "1.0.0"