@nestia/migrate 7.0.0-dev.20250608 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -92
- package/lib/analyzers/NestiaMigrateControllerAnalyzer.js +1 -1
- package/lib/analyzers/NestiaMigrateControllerAnalyzer.js.map +1 -1
- package/lib/bundles/NEST_TEMPLATE.js +47 -47
- package/lib/bundles/NEST_TEMPLATE.js.map +1 -1
- package/lib/bundles/SDK_TEMPLATE.js +21 -21
- package/lib/bundles/SDK_TEMPLATE.js.map +1 -1
- package/lib/index.mjs +69 -69
- package/lib/index.mjs.map +1 -1
- package/lib/utils/openapi-down-convert/converter.js +2 -2
- package/package.json +7 -7
- package/src/NestiaMigrateApplication.ts +144 -144
- package/src/analyzers/NestiaMigrateControllerAnalyzer.ts +51 -51
- package/src/archivers/NestiaMigrateFileArchiver.ts +28 -28
- package/src/bundles/NEST_TEMPLATE.ts +47 -47
- package/src/bundles/SDK_TEMPLATE.ts +21 -21
- package/src/executable/NestiaMigrateCommander.ts +98 -98
- package/src/executable/NestiaMigrateInquirer.ts +106 -106
- package/src/executable/bundle.js +129 -129
- package/src/executable/migrate.ts +7 -7
- package/src/factories/TypeLiteralFactory.ts +57 -57
- package/src/index.ts +4 -4
- package/src/module.ts +2 -2
- package/src/programmers/NestiaMigrateApiFileProgrammer.ts +55 -55
- package/src/programmers/NestiaMigrateApiFunctionProgrammer.ts +256 -256
- package/src/programmers/NestiaMigrateApiNamespaceProgrammer.ts +515 -515
- package/src/programmers/NestiaMigrateApiProgrammer.ts +107 -107
- package/src/programmers/NestiaMigrateApiSimulationProgrammer.ts +340 -340
- package/src/programmers/NestiaMigrateApiStartProgrammer.ts +198 -198
- package/src/programmers/NestiaMigrateDtoProgrammer.ts +101 -101
- package/src/programmers/NestiaMigrateE2eFileProgrammer.ts +153 -153
- package/src/programmers/NestiaMigrateE2eProgrammer.ts +46 -46
- package/src/programmers/NestiaMigrateImportProgrammer.ts +118 -118
- package/src/programmers/NestiaMigrateNestControllerProgrammer.ts +66 -66
- package/src/programmers/NestiaMigrateNestMethodProgrammer.ts +406 -406
- package/src/programmers/NestiaMigrateNestModuleProgrammer.ts +65 -65
- package/src/programmers/NestiaMigrateNestProgrammer.ts +88 -88
- package/src/programmers/NestiaMigrateSchemaProgrammer.ts +475 -475
- package/src/structures/INestiaMigrateConfig.ts +10 -10
- package/src/structures/INestiaMigrateContext.ts +15 -15
- package/src/structures/INestiaMigrateController.ts +8 -8
- package/src/structures/INestiaMigrateDto.ts +8 -8
- package/src/structures/INestiaMigrateFile.ts +5 -5
- package/src/structures/INestiaMigrateProgram.ts +11 -11
- package/src/structures/INestiaMigrateSchema.ts +4 -4
- package/src/utils/FilePrinter.ts +38 -38
- package/src/utils/MapUtil.ts +13 -13
- package/src/utils/OpenApiTypeChecker.ts +73 -73
- package/src/utils/SetupWizard.ts +12 -12
- package/src/utils/StringUtil.ts +113 -113
- package/src/utils/openapi-down-convert/RefVisitor.ts +139 -139
- package/src/utils/openapi-down-convert/converter.ts +527 -527
@@ -1,144 +1,144 @@
|
|
1
|
-
import {
|
2
|
-
HttpMigration,
|
3
|
-
IHttpMigrateApplication,
|
4
|
-
OpenApi,
|
5
|
-
OpenApiV3,
|
6
|
-
OpenApiV3_1,
|
7
|
-
SwaggerV2,
|
8
|
-
} from "@samchon/openapi";
|
9
|
-
import typia, { IValidation } from "typia";
|
10
|
-
|
11
|
-
import { NEST_TEMPLATE } from "./bundles/NEST_TEMPLATE";
|
12
|
-
import { SDK_TEMPLATE } from "./bundles/SDK_TEMPLATE";
|
13
|
-
import { NestiaMigrateApiProgrammer } from "./programmers/NestiaMigrateApiProgrammer";
|
14
|
-
import { NestiaMigrateApiStartProgrammer } from "./programmers/NestiaMigrateApiStartProgrammer";
|
15
|
-
import { NestiaMigrateE2eProgrammer } from "./programmers/NestiaMigrateE2eProgrammer";
|
16
|
-
import { NestiaMigrateNestProgrammer } from "./programmers/NestiaMigrateNestProgrammer";
|
17
|
-
import { INestiaMigrateConfig } from "./structures/INestiaMigrateConfig";
|
18
|
-
import { INestiaMigrateContext } from "./structures/INestiaMigrateContext";
|
19
|
-
import { INestiaMigrateFile } from "./structures/INestiaMigrateFile";
|
20
|
-
|
21
|
-
export class NestiaMigrateApplication {
|
22
|
-
private readonly application_: IHttpMigrateApplication;
|
23
|
-
|
24
|
-
public constructor(public readonly document: OpenApi.IDocument) {
|
25
|
-
this.application_ = HttpMigration.application(document);
|
26
|
-
}
|
27
|
-
|
28
|
-
public static assert(
|
29
|
-
document:
|
30
|
-
| SwaggerV2.IDocument
|
31
|
-
| OpenApiV3.IDocument
|
32
|
-
| OpenApiV3_1.IDocument
|
33
|
-
| OpenApi.IDocument,
|
34
|
-
): NestiaMigrateApplication {
|
35
|
-
return new NestiaMigrateApplication(
|
36
|
-
OpenApi.convert(typia.assert(document)),
|
37
|
-
);
|
38
|
-
}
|
39
|
-
|
40
|
-
public static validate(
|
41
|
-
document:
|
42
|
-
| SwaggerV2.IDocument
|
43
|
-
| OpenApiV3.IDocument
|
44
|
-
| OpenApiV3_1.IDocument
|
45
|
-
| OpenApi.IDocument,
|
46
|
-
): IValidation<NestiaMigrateApplication> {
|
47
|
-
const result: IValidation<
|
48
|
-
| SwaggerV2.IDocument
|
49
|
-
| OpenApiV3.IDocument
|
50
|
-
| OpenApiV3_1.IDocument
|
51
|
-
| OpenApi.IDocument
|
52
|
-
> = typia.validate(document);
|
53
|
-
if (result.success === false) return result;
|
54
|
-
return {
|
55
|
-
success: true,
|
56
|
-
data: new NestiaMigrateApplication(OpenApi.convert(document)),
|
57
|
-
};
|
58
|
-
}
|
59
|
-
|
60
|
-
public getErrors(): IHttpMigrateApplication.IError[] {
|
61
|
-
return this.application_.errors;
|
62
|
-
}
|
63
|
-
|
64
|
-
public nest(config: INestiaMigrateConfig): Record<string, string> {
|
65
|
-
const context: INestiaMigrateContext = createContext(
|
66
|
-
"nest",
|
67
|
-
this.document,
|
68
|
-
config,
|
69
|
-
);
|
70
|
-
const files: Record<string, string> = {
|
71
|
-
...Object.fromEntries(
|
72
|
-
Object.entries(NEST_TEMPLATE).filter(
|
73
|
-
([key]) =>
|
74
|
-
key.startsWith("src/api/structures") === false &&
|
75
|
-
key.startsWith("src/api/functional") === false &&
|
76
|
-
key.startsWith("src/api/controllers") === false &&
|
77
|
-
key.startsWith("test/features") === false,
|
78
|
-
),
|
79
|
-
),
|
80
|
-
...NestiaMigrateNestProgrammer.write(context),
|
81
|
-
...NestiaMigrateApiProgrammer.write(context),
|
82
|
-
...(config.e2e ? NestiaMigrateE2eProgrammer.write(context) : {}),
|
83
|
-
};
|
84
|
-
return config.package ? this.rename(config.package, files) : files;
|
85
|
-
}
|
86
|
-
|
87
|
-
public sdk(config: INestiaMigrateConfig): Record<string, string> {
|
88
|
-
const context: INestiaMigrateContext = createContext(
|
89
|
-
"sdk",
|
90
|
-
this.document,
|
91
|
-
config,
|
92
|
-
);
|
93
|
-
const files: Record<string, string> = {
|
94
|
-
...Object.fromEntries(
|
95
|
-
Object.entries(SDK_TEMPLATE).filter(
|
96
|
-
([key]) =>
|
97
|
-
key.startsWith("src/structures") === false &&
|
98
|
-
key.startsWith("src/functional") === false &&
|
99
|
-
key.startsWith("test/features") === false,
|
100
|
-
),
|
101
|
-
),
|
102
|
-
...NestiaMigrateApiProgrammer.write(context),
|
103
|
-
...NestiaMigrateApiStartProgrammer.write(context),
|
104
|
-
...(config.e2e ? NestiaMigrateE2eProgrammer.write(context) : {}),
|
105
|
-
"swagger.json": JSON.stringify(this.document, null, 2),
|
106
|
-
};
|
107
|
-
return config.package ? this.rename(config.package, files) : files;
|
108
|
-
}
|
109
|
-
|
110
|
-
private rename(
|
111
|
-
slug: string,
|
112
|
-
files: Record<string, string>,
|
113
|
-
): Record<string, string> {
|
114
|
-
return Object.fromEntries(
|
115
|
-
Object.entries(files).map(([key, value]) => [
|
116
|
-
key,
|
117
|
-
value.split(`@ORGANIZATION/PROJECT`).join(slug),
|
118
|
-
]),
|
119
|
-
);
|
120
|
-
}
|
121
|
-
}
|
122
|
-
export namespace MigrateApplication {
|
123
|
-
export interface IOutput {
|
124
|
-
context: INestiaMigrateContext;
|
125
|
-
files: INestiaMigrateFile[];
|
126
|
-
errors: IHttpMigrateApplication.IError[];
|
127
|
-
}
|
128
|
-
}
|
129
|
-
|
130
|
-
const createContext = (
|
131
|
-
mode: "nest" | "sdk",
|
132
|
-
document: OpenApi.IDocument,
|
133
|
-
config: INestiaMigrateConfig,
|
134
|
-
): INestiaMigrateContext => {
|
135
|
-
const application: IHttpMigrateApplication =
|
136
|
-
HttpMigration.application(document);
|
137
|
-
return {
|
138
|
-
mode,
|
139
|
-
document,
|
140
|
-
config,
|
141
|
-
routes: application.routes,
|
142
|
-
errors: application.errors,
|
143
|
-
};
|
144
|
-
};
|
1
|
+
import {
|
2
|
+
HttpMigration,
|
3
|
+
IHttpMigrateApplication,
|
4
|
+
OpenApi,
|
5
|
+
OpenApiV3,
|
6
|
+
OpenApiV3_1,
|
7
|
+
SwaggerV2,
|
8
|
+
} from "@samchon/openapi";
|
9
|
+
import typia, { IValidation } from "typia";
|
10
|
+
|
11
|
+
import { NEST_TEMPLATE } from "./bundles/NEST_TEMPLATE";
|
12
|
+
import { SDK_TEMPLATE } from "./bundles/SDK_TEMPLATE";
|
13
|
+
import { NestiaMigrateApiProgrammer } from "./programmers/NestiaMigrateApiProgrammer";
|
14
|
+
import { NestiaMigrateApiStartProgrammer } from "./programmers/NestiaMigrateApiStartProgrammer";
|
15
|
+
import { NestiaMigrateE2eProgrammer } from "./programmers/NestiaMigrateE2eProgrammer";
|
16
|
+
import { NestiaMigrateNestProgrammer } from "./programmers/NestiaMigrateNestProgrammer";
|
17
|
+
import { INestiaMigrateConfig } from "./structures/INestiaMigrateConfig";
|
18
|
+
import { INestiaMigrateContext } from "./structures/INestiaMigrateContext";
|
19
|
+
import { INestiaMigrateFile } from "./structures/INestiaMigrateFile";
|
20
|
+
|
21
|
+
export class NestiaMigrateApplication {
|
22
|
+
private readonly application_: IHttpMigrateApplication;
|
23
|
+
|
24
|
+
public constructor(public readonly document: OpenApi.IDocument) {
|
25
|
+
this.application_ = HttpMigration.application(document);
|
26
|
+
}
|
27
|
+
|
28
|
+
public static assert(
|
29
|
+
document:
|
30
|
+
| SwaggerV2.IDocument
|
31
|
+
| OpenApiV3.IDocument
|
32
|
+
| OpenApiV3_1.IDocument
|
33
|
+
| OpenApi.IDocument,
|
34
|
+
): NestiaMigrateApplication {
|
35
|
+
return new NestiaMigrateApplication(
|
36
|
+
OpenApi.convert(typia.assert(document)),
|
37
|
+
);
|
38
|
+
}
|
39
|
+
|
40
|
+
public static validate(
|
41
|
+
document:
|
42
|
+
| SwaggerV2.IDocument
|
43
|
+
| OpenApiV3.IDocument
|
44
|
+
| OpenApiV3_1.IDocument
|
45
|
+
| OpenApi.IDocument,
|
46
|
+
): IValidation<NestiaMigrateApplication> {
|
47
|
+
const result: IValidation<
|
48
|
+
| SwaggerV2.IDocument
|
49
|
+
| OpenApiV3.IDocument
|
50
|
+
| OpenApiV3_1.IDocument
|
51
|
+
| OpenApi.IDocument
|
52
|
+
> = typia.validate(document);
|
53
|
+
if (result.success === false) return result;
|
54
|
+
return {
|
55
|
+
success: true,
|
56
|
+
data: new NestiaMigrateApplication(OpenApi.convert(document)),
|
57
|
+
};
|
58
|
+
}
|
59
|
+
|
60
|
+
public getErrors(): IHttpMigrateApplication.IError[] {
|
61
|
+
return this.application_.errors;
|
62
|
+
}
|
63
|
+
|
64
|
+
public nest(config: INestiaMigrateConfig): Record<string, string> {
|
65
|
+
const context: INestiaMigrateContext = createContext(
|
66
|
+
"nest",
|
67
|
+
this.document,
|
68
|
+
config,
|
69
|
+
);
|
70
|
+
const files: Record<string, string> = {
|
71
|
+
...Object.fromEntries(
|
72
|
+
Object.entries(NEST_TEMPLATE).filter(
|
73
|
+
([key]) =>
|
74
|
+
key.startsWith("src/api/structures") === false &&
|
75
|
+
key.startsWith("src/api/functional") === false &&
|
76
|
+
key.startsWith("src/api/controllers") === false &&
|
77
|
+
key.startsWith("test/features") === false,
|
78
|
+
),
|
79
|
+
),
|
80
|
+
...NestiaMigrateNestProgrammer.write(context),
|
81
|
+
...NestiaMigrateApiProgrammer.write(context),
|
82
|
+
...(config.e2e ? NestiaMigrateE2eProgrammer.write(context) : {}),
|
83
|
+
};
|
84
|
+
return config.package ? this.rename(config.package, files) : files;
|
85
|
+
}
|
86
|
+
|
87
|
+
public sdk(config: INestiaMigrateConfig): Record<string, string> {
|
88
|
+
const context: INestiaMigrateContext = createContext(
|
89
|
+
"sdk",
|
90
|
+
this.document,
|
91
|
+
config,
|
92
|
+
);
|
93
|
+
const files: Record<string, string> = {
|
94
|
+
...Object.fromEntries(
|
95
|
+
Object.entries(SDK_TEMPLATE).filter(
|
96
|
+
([key]) =>
|
97
|
+
key.startsWith("src/structures") === false &&
|
98
|
+
key.startsWith("src/functional") === false &&
|
99
|
+
key.startsWith("test/features") === false,
|
100
|
+
),
|
101
|
+
),
|
102
|
+
...NestiaMigrateApiProgrammer.write(context),
|
103
|
+
...NestiaMigrateApiStartProgrammer.write(context),
|
104
|
+
...(config.e2e ? NestiaMigrateE2eProgrammer.write(context) : {}),
|
105
|
+
"swagger.json": JSON.stringify(this.document, null, 2),
|
106
|
+
};
|
107
|
+
return config.package ? this.rename(config.package, files) : files;
|
108
|
+
}
|
109
|
+
|
110
|
+
private rename(
|
111
|
+
slug: string,
|
112
|
+
files: Record<string, string>,
|
113
|
+
): Record<string, string> {
|
114
|
+
return Object.fromEntries(
|
115
|
+
Object.entries(files).map(([key, value]) => [
|
116
|
+
key,
|
117
|
+
value.split(`@ORGANIZATION/PROJECT`).join(slug),
|
118
|
+
]),
|
119
|
+
);
|
120
|
+
}
|
121
|
+
}
|
122
|
+
export namespace MigrateApplication {
|
123
|
+
export interface IOutput {
|
124
|
+
context: INestiaMigrateContext;
|
125
|
+
files: INestiaMigrateFile[];
|
126
|
+
errors: IHttpMigrateApplication.IError[];
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
const createContext = (
|
131
|
+
mode: "nest" | "sdk",
|
132
|
+
document: OpenApi.IDocument,
|
133
|
+
config: INestiaMigrateConfig,
|
134
|
+
): INestiaMigrateContext => {
|
135
|
+
const application: IHttpMigrateApplication =
|
136
|
+
HttpMigration.application(document);
|
137
|
+
return {
|
138
|
+
mode,
|
139
|
+
document,
|
140
|
+
config,
|
141
|
+
routes: application.routes,
|
142
|
+
errors: application.errors,
|
143
|
+
};
|
144
|
+
};
|
@@ -1,51 +1,51 @@
|
|
1
|
-
import { IHttpMigrateRoute } from "@samchon/openapi";
|
2
|
-
|
3
|
-
import { INestiaMigrateController } from "../structures/INestiaMigrateController";
|
4
|
-
import { MapUtil } from "../utils/MapUtil";
|
5
|
-
import { StringUtil } from "../utils/StringUtil";
|
6
|
-
|
7
|
-
export namespace NestiaMigrateControllerAnalyzer {
|
8
|
-
export const analyze = (
|
9
|
-
routes: IHttpMigrateRoute[],
|
10
|
-
): INestiaMigrateController[] => {
|
11
|
-
const collection: Map<string, INestiaMigrateController> = new Map();
|
12
|
-
for (const r of routes) {
|
13
|
-
const name: string =
|
14
|
-
r.operation()["x-samchon-controller"] ??
|
15
|
-
(r.accessor.length <= 1
|
16
|
-
? "__App"
|
17
|
-
: r.accessor.slice(0, -1).map(StringUtil.capitalize).join("")) +
|
18
|
-
"Controller";
|
19
|
-
MapUtil.take(collection)(name)(() => ({
|
20
|
-
name,
|
21
|
-
path: "@lazy",
|
22
|
-
location: "@lazy",
|
23
|
-
routes: [],
|
24
|
-
})).routes.push(r);
|
25
|
-
}
|
26
|
-
|
27
|
-
const controllers: INestiaMigrateController[] = [...collection.values()];
|
28
|
-
for (const col of controllers) {
|
29
|
-
const splitPath = (r: IHttpMigrateRoute): string[] =>
|
30
|
-
r.emendedPath.split("/");
|
31
|
-
const splitLocation = (r: IHttpMigrateRoute): string[] =>
|
32
|
-
splitPath(r).filter((s) => s.length !== 0 && s[0] !== ":");
|
33
|
-
|
34
|
-
const minPath: string[] = splitPath(col.routes[0]);
|
35
|
-
const minLocation: string[] = splitLocation(col.routes[0]);
|
36
|
-
for (const r of col.routes.slice(1)) {
|
37
|
-
minPath.splice(getSplitIndex(minPath, splitPath(r)));
|
38
|
-
minLocation.splice(getSplitIndex(minLocation, splitLocation(r)));
|
39
|
-
}
|
40
|
-
col.path = minPath.join("/");
|
41
|
-
col.location =
|
42
|
-
}
|
43
|
-
return controllers;
|
44
|
-
};
|
45
|
-
}
|
46
|
-
|
47
|
-
const getSplitIndex = (x: string[], y: string[]) => {
|
48
|
-
const n: number = Math.min(x.length, y.length);
|
49
|
-
for (let i: number = 0; i < n; ++i) if (x[i] !== y[i]) return i;
|
50
|
-
return n;
|
51
|
-
};
|
1
|
+
import { IHttpMigrateRoute } from "@samchon/openapi";
|
2
|
+
|
3
|
+
import { INestiaMigrateController } from "../structures/INestiaMigrateController";
|
4
|
+
import { MapUtil } from "../utils/MapUtil";
|
5
|
+
import { StringUtil } from "../utils/StringUtil";
|
6
|
+
|
7
|
+
export namespace NestiaMigrateControllerAnalyzer {
|
8
|
+
export const analyze = (
|
9
|
+
routes: IHttpMigrateRoute[],
|
10
|
+
): INestiaMigrateController[] => {
|
11
|
+
const collection: Map<string, INestiaMigrateController> = new Map();
|
12
|
+
for (const r of routes) {
|
13
|
+
const name: string =
|
14
|
+
r.operation()["x-samchon-controller"] ??
|
15
|
+
(r.accessor.length <= 1
|
16
|
+
? "__App"
|
17
|
+
: r.accessor.slice(0, -1).map(StringUtil.capitalize).join("")) +
|
18
|
+
"Controller";
|
19
|
+
MapUtil.take(collection)(name)(() => ({
|
20
|
+
name,
|
21
|
+
path: "@lazy",
|
22
|
+
location: "@lazy",
|
23
|
+
routes: [],
|
24
|
+
})).routes.push(r);
|
25
|
+
}
|
26
|
+
|
27
|
+
const controllers: INestiaMigrateController[] = [...collection.values()];
|
28
|
+
for (const col of controllers) {
|
29
|
+
const splitPath = (r: IHttpMigrateRoute): string[] =>
|
30
|
+
r.emendedPath.split("/");
|
31
|
+
const splitLocation = (r: IHttpMigrateRoute): string[] =>
|
32
|
+
splitPath(r).filter((s) => s.length !== 0 && s[0] !== ":");
|
33
|
+
|
34
|
+
const minPath: string[] = splitPath(col.routes[0]);
|
35
|
+
const minLocation: string[] = splitLocation(col.routes[0]);
|
36
|
+
for (const r of col.routes.slice(1)) {
|
37
|
+
minPath.splice(getSplitIndex(minPath, splitPath(r)));
|
38
|
+
minLocation.splice(getSplitIndex(minLocation, splitLocation(r)));
|
39
|
+
}
|
40
|
+
col.path = minPath.join("/");
|
41
|
+
col.location = ["src", "controllers", ...minLocation].join("/");
|
42
|
+
}
|
43
|
+
return controllers;
|
44
|
+
};
|
45
|
+
}
|
46
|
+
|
47
|
+
const getSplitIndex = (x: string[], y: string[]) => {
|
48
|
+
const n: number = Math.min(x.length, y.length);
|
49
|
+
for (let i: number = 0; i < n; ++i) if (x[i] !== y[i]) return i;
|
50
|
+
return n;
|
51
|
+
};
|
@@ -1,28 +1,28 @@
|
|
1
|
-
import { VariadicSingleton } from "tstl";
|
2
|
-
|
3
|
-
export namespace NestiaMigrateFileArchiver {
|
4
|
-
export const archive = async (props: {
|
5
|
-
mkdir: (path: string) => Promise<void>;
|
6
|
-
writeFile: (path: string, content: string) => Promise<void>;
|
7
|
-
root: string;
|
8
|
-
files: Record<string, string>;
|
9
|
-
}): Promise<void> => {
|
10
|
-
const mkdir = new VariadicSingleton(
|
11
|
-
async (location: string): Promise<void> => {
|
12
|
-
try {
|
13
|
-
await props.mkdir(`${props.root}/${location}`);
|
14
|
-
} catch {}
|
15
|
-
},
|
16
|
-
);
|
17
|
-
const iterate = async (location: string): Promise<void> => {
|
18
|
-
const sequence: string[] = location
|
19
|
-
.split("/")
|
20
|
-
.map((_str, i, entire) => entire.slice(0, i + 1).join("/"));
|
21
|
-
for (const s of sequence) await mkdir.get(s);
|
22
|
-
};
|
23
|
-
for (const [key, value] of Object.entries(props.files)) {
|
24
|
-
await iterate(key.split("/").slice(0, -1).join("/"));
|
25
|
-
await props.writeFile(`${props.root}/${key}`, value);
|
26
|
-
}
|
27
|
-
};
|
28
|
-
}
|
1
|
+
import { VariadicSingleton } from "tstl";
|
2
|
+
|
3
|
+
export namespace NestiaMigrateFileArchiver {
|
4
|
+
export const archive = async (props: {
|
5
|
+
mkdir: (path: string) => Promise<void>;
|
6
|
+
writeFile: (path: string, content: string) => Promise<void>;
|
7
|
+
root: string;
|
8
|
+
files: Record<string, string>;
|
9
|
+
}): Promise<void> => {
|
10
|
+
const mkdir = new VariadicSingleton(
|
11
|
+
async (location: string): Promise<void> => {
|
12
|
+
try {
|
13
|
+
await props.mkdir(`${props.root}/${location}`);
|
14
|
+
} catch {}
|
15
|
+
},
|
16
|
+
);
|
17
|
+
const iterate = async (location: string): Promise<void> => {
|
18
|
+
const sequence: string[] = location
|
19
|
+
.split("/")
|
20
|
+
.map((_str, i, entire) => entire.slice(0, i + 1).join("/"));
|
21
|
+
for (const s of sequence) await mkdir.get(s);
|
22
|
+
};
|
23
|
+
for (const [key, value] of Object.entries(props.files)) {
|
24
|
+
await iterate(key.split("/").slice(0, -1).join("/"));
|
25
|
+
await props.writeFile(`${props.root}/${key}`, value);
|
26
|
+
}
|
27
|
+
};
|
28
|
+
}
|