Skip to content

Commit

Permalink
Merge pull request #512 from samchon/features/primitive
Browse files Browse the repository at this point in the history
Close #511 - `random()` became customizable
  • Loading branch information
samchon committed Feb 19, 2023
2 parents 4e0db58 + d265bc8 commit b2fa3fe
Show file tree
Hide file tree
Showing 21 changed files with 418 additions and 241 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function assertStringify<T>(input: T): string; // safe and faster

// MISC
export function random<T>(): Primitive<T>; // generate random data
export function clone<T>(input: T): Primitive<T>; // hard copy
export function clone<T>(input: T): Primitive<T>; // deep clone
export function prune<T extends object>(input: T): void; // erase extra props
// +) isClone, assertClone, validateClone
// +) isPrune, assertPrune, validatePrune
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typia",
"version": "3.5.3",
"version": "3.5.4",
"description": "Superfast runtime validators with only one line",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/typescript-json/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function assertStringify<T>(input: T): string; // safe and faster

// MISC
export function random<T>(): Primitive<T>; // generate random data
export function clone<T>(input: T): Primitive<T>; // hard copy
export function clone<T>(input: T): Primitive<T>; // deep clone
export function prune<T extends object>(input: T): void; // erase extra props
// +) isClone, assertClone, validateClone
// +) isPrune, assertPrune, validatePrune
Expand Down
4 changes: 2 additions & 2 deletions packages/typescript-json/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typescript-json",
"version": "3.5.3",
"version": "3.5.4",
"description": "Superfast runtime validators with only one line",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -72,6 +72,6 @@
"src"
],
"dependencies": {
"typia": "3.5.3"
"typia": "3.5.4"
}
}
16 changes: 8 additions & 8 deletions src/IRandomGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
export interface IRandomGenerator {
boolean(): boolean;
int(minimum?: number, maximum?: number): number;
integer(minimum?: number, maximum?: number): number;
number(minimum?: number, maximum?: number): number;
bigint(minimum?: bigint, maximum?: bigint): bigint;
string(length?: number): string;
array<T>(closure: (index: number) => T, count?: number): T[];

uuid?(): string;
email?(): string;
url?(): string;
ipv4?(): string;
ipv6?(): string;
pattern?(regex: RegExp): string;
date?(): string;
uuid(): string;
email(): string;
url(): string;
ipv4(): string;
ipv6(): string;
pattern(regex: RegExp): string;
date(): string;
}
Original file line number Diff line number Diff line change
@@ -1,81 +1,71 @@
import type CommanderModule from "commander";
import fs from "fs";
import type * as InquirerModule from "inquirer";
import path from "path";

import { PackageManager } from "./PackageManager";
import { ArgumentParser } from "./setup/ArgumentParser";
import { CommandExecutor } from "./setup/CommandExecutor";
import { PackageManager } from "./setup/PackageManager";
import { PluginConfigurator } from "./setup/PluginConfigurator";

export namespace ArgumentParser {
export namespace TypiaSetupWizard {
export interface IArguments {
compiler: "ts-patch" | "ttypescript";
manager: "npm" | "pnpm" | "yarn";
project: string | null;
}

export async function parse(pack: PackageManager): Promise<IArguments> {
// INSTALL TEMPORARY PACKAGES
const newbie = {
commander: pack.install({
dev: true,
modulo: "commander",
version: "10.0.0",
silent: true,
}),
inquirer: pack.install({
dev: true,
modulo: "inquirer",
version: "8.2.5",
silent: true,
}),
};
export async function setup(): Promise<void> {
console.log("----------------------------------------");
console.log(" Typia Setup Wizard");
console.log("----------------------------------------");

// TAKE OPTIONS
const output: IArguments | Error = await (async () => {
try {
return await _Parse(pack);
} catch (error) {
return error as Error;
}
// PREPARE ASSETS
const pack: PackageManager = await PackageManager.mount();
const args: IArguments = await ArgumentParser.parse(pack)(true)(
inquiry,
);

// INSTALL TYPESCRIPT
pack.install({ dev: true, modulo: "typescript" });
args.project ??= (() => {
CommandExecutor.run("npx tsc --init", false);
return (args.project = "tsconfig.json");
})();
pack.install({ dev: true, modulo: "ts-node" });

// REMOVE TEMPORARY PACKAGES
if (newbie.commander) pack.erase({ modulo: "commander", silent: true });
if (newbie.inquirer) pack.erase({ modulo: "inquirer", silent: true });
// INSTALL COMPILER
pack.install({ dev: true, modulo: args.compiler });
if (args.compiler === "ts-patch") {
await pack.save((data) => {
data.scripts ??= {};
if (
typeof data.scripts.prepare === "string" &&
data.scripts.prepare.indexOf("ts-patch install") === -1
)
data.scripts.prepare =
"ts-patch install && " + data.scripts.prepare;
else data.scripts.prepare = "ts-patch install";
});
CommandExecutor.run("npm run prepare", false);
}

// RETURNS
if (output instanceof Error) throw output;
return output;
// INSTALL AND CONFIGURE TYPIA
pack.install({ dev: false, modulo: "typia" });
await PluginConfigurator.configure(pack, args);
}

async function _Parse(pack: PackageManager): Promise<IArguments> {
const inquiry: ArgumentParser.Inquiry<IArguments> = async (
pack,
command,
prompt,
action,
) => {
// PREPARE ASSETS
const { createPromptModule }: typeof InquirerModule = await import(
path.join(pack.directory, "node_modules", "inquirer")
);
const { program }: typeof CommanderModule = await import(
path.join(pack.directory, "node_modules", "commander")
);

program.option("--compiler [compiler]", "compiler type");
program.option("--manager [manager", "package manager");
program.option("--project [project]", "tsconfig.json file location");
command.option("--compiler [compiler]", "compiler type");
command.option("--manager [manager", "package manager");
command.option("--project [project]", "tsconfig.json file location");

// INTERNAL PROCEDURES
const questioned = { value: false };
const action = (
closure: (options: Partial<IArguments>) => Promise<IArguments>,
) => {
return new Promise<IArguments>((resolve, reject) => {
program.action(async (options) => {
try {
resolve(await closure(options));
} catch (exp) {
reject(exp);
}
});
program.parseAsync().catch(reject);
});
};
const select =
(name: string) =>
(message: string) =>
Expand All @@ -84,7 +74,7 @@ export namespace ArgumentParser {
): Promise<Choice> => {
questioned.value = true;
return (
await createPromptModule()({
await prompt()({
type: "list",
name: name,
message: message,
Expand Down Expand Up @@ -113,7 +103,7 @@ export namespace ArgumentParser {
if (options.compiler === undefined) {
console.log(COMPILER_DESCRIPTION);
options.compiler = await select("compiler")(`Compiler`)(
pack.data.scripts?.build === "nest build"
is_nest_cli(pack)
? ["ts-patch" as const, "ttypescript" as const]
: ["ttypescript" as const, "ts-patch" as const],
);
Expand All @@ -129,6 +119,14 @@ export namespace ArgumentParser {
if (questioned.value) console.log("");
return options as IArguments;
});
};

function is_nest_cli(pack: PackageManager): boolean {
return (
(typeof pack.data.scripts?.build === "string" &&
pack.data.scripts.build.indexOf("nest build") !== -1) ||
fs.existsSync(path.join(pack.directory, "nest-cli.json"))
);
}
}

Expand Down
89 changes: 89 additions & 0 deletions src/executable/setup/ArgumentParser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import type CommanderModule from "commander";
import type * as InquirerModule from "inquirer";
import path from "path";

import { PackageManager } from "./PackageManager";

export namespace ArgumentParser {
export type Inquiry<T> = (
pack: PackageManager,
command: CommanderModule.Command,
prompt: (
opt?: InquirerModule.StreamOptions,
) => InquirerModule.PromptModule,
action: (closure: (options: Partial<T>) => Promise<T>) => Promise<T>,
) => Promise<T>;

export const parse =
(pack: PackageManager) =>
(erase: boolean) =>
async <T>(
inquiry: (
pack: PackageManager,
command: CommanderModule.Command,
prompt: (
opt?: InquirerModule.StreamOptions,
) => InquirerModule.PromptModule,
action: (
closure: (options: Partial<T>) => Promise<T>,
) => Promise<T>,
) => Promise<T>,
): Promise<T> => {
// INSTALL TEMPORARY PACKAGES
const newbie = {
commander: pack.install({
dev: true,
modulo: "commander",
version: "10.0.0",
silent: true,
}),
inquirer: pack.install({
dev: true,
modulo: "inquirer",
version: "8.2.5",
silent: true,
}),
};

// LOAD INSTALLED MODULES
const { program: command }: typeof CommanderModule = await import(
path.join(pack.directory, "node_modules", "commander")
);
const { createPromptModule: prompt }: typeof InquirerModule =
await import(
path.join(pack.directory, "node_modules", "inquirer")
);

// TAKE OPTIONS
const action = (closure: (options: Partial<T>) => Promise<T>) =>
new Promise<T>((resolve, reject) => {
command.action(async (options) => {
try {
resolve(await closure(options));
} catch (exp) {
reject(exp);
}
});
command.parseAsync().catch(reject);
});
const output: T | Error = await (async () => {
try {
return await inquiry(pack, command, prompt, action);
} catch (error) {
return error as Error;
}
})();

// REMOVE TEMPORARY PACKAGES
if (erase === true) {
if (newbie.commander)
pack.erase({ modulo: "commander", silent: true });
if (newbie.inquirer)
pack.erase({ modulo: "inquirer", silent: true });
}

// RETURNS
if (output instanceof Error) throw output;
return output;
};
}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import type Comment from "comment-json";
import fs from "fs";
import path from "path";

import { ArgumentParser } from "./ArgumentParser";
import { TypiaSetupWizard } from "../TypiaSetupWizard";
import { PackageManager } from "./PackageManager";

export namespace PluginConfigurator {
export async function configure(
pack: PackageManager,
args: ArgumentParser.IArguments,
args: TypiaSetupWizard.IArguments,
): Promise<void> {
// INSTALL COMMENT-JSON
const installed: boolean = pack.install({
Expand Down Expand Up @@ -39,7 +39,7 @@ export namespace PluginConfigurator {

async function _Configure(
pack: PackageManager,
args: ArgumentParser.IArguments,
args: TypiaSetupWizard.IArguments,
): Promise<void> {
// GET COMPILER-OPTIONS
const Comment: typeof import("comment-json") = await import(
Expand Down

0 comments on commit b2fa3fe

Please sign in to comment.