@codeandmoney/jargal 0.0.2-RC.5 → 0.0.2-RC.6
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/actions/exports.ts +3 -3
- package/actions/{load_templates.ts → load-templates.ts} +3 -3
- package/actions/{render_template.ts → render-template.ts} +6 -3
- package/actions/{select_generator.ts → select-generator.ts} +1 -1
- package/actions/write.ts +23 -20
- package/deno.json +1 -1
- package/package.json +31 -31
- package/{runner_test.ts → runner.test.ts} +8 -5
- package/runner.ts +13 -8
- package/types.ts +3 -1
- /package/actions/{validate_answers.ts → validate-answers.ts} +0 -0
package/actions/exports.ts
CHANGED
|
@@ -3,6 +3,6 @@ export { prompt } from "./prompt.ts"
|
|
|
3
3
|
export { parallel } from "./parallel.ts"
|
|
4
4
|
export { write } from "./write.ts"
|
|
5
5
|
export { echo } from "./echo.ts"
|
|
6
|
-
export { validateAnswers } from "./
|
|
7
|
-
export { loadTemplates } from "./
|
|
8
|
-
export { renderTemplate } from "./
|
|
6
|
+
export { validateAnswers } from "./validate-answers.ts"
|
|
7
|
+
export { loadTemplates } from "./load-templates.ts"
|
|
8
|
+
export { renderTemplate } from "./render-template.ts"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ContextAction } from "../types.ts"
|
|
2
|
-
import {
|
|
2
|
+
import { readdir, readFile } from "node:fs/promises"
|
|
3
3
|
import path from "node:path"
|
|
4
4
|
|
|
5
5
|
export function loadTemplates( templatesPath: string ): ContextAction {
|
|
@@ -9,7 +9,7 @@ export function loadTemplates( templatesPath: string ): ContextAction {
|
|
|
9
9
|
for await ( const fullPath of walkDir( templatesPath ) ) {
|
|
10
10
|
const realativePath = path.relative( templatesPath, fullPath )
|
|
11
11
|
|
|
12
|
-
const contentRaw = await
|
|
12
|
+
const contentRaw = await readFile( path.resolve( templatesPath, fullPath ) )
|
|
13
13
|
|
|
14
14
|
templates.set( realativePath, { content: new TextDecoder().decode( contentRaw ), fullPath, realativePath } )
|
|
15
15
|
}
|
|
@@ -19,7 +19,7 @@ export function loadTemplates( templatesPath: string ): ContextAction {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async function* walkDir( dir: string ): AsyncGenerator<string, void, void> {
|
|
22
|
-
const entries = await
|
|
22
|
+
const entries = await readdir( dir, { withFileTypes: true } )
|
|
23
23
|
|
|
24
24
|
for ( const entry of entries ) {
|
|
25
25
|
const fullPath = path.join( dir, entry.name )
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type { Action, Context } from "../types.ts"
|
|
2
|
-
import type { WriteActionConfig } from "./write.ts"
|
|
3
2
|
|
|
4
3
|
export function renderTemplate( { fullpath, template, getData, write }: {
|
|
5
4
|
template: string
|
|
6
5
|
fullpath: string
|
|
7
6
|
getData?: ( ctx: Context ) => Record<string, unknown>
|
|
8
|
-
write?:
|
|
7
|
+
write?: Action<{ content?: string; destination?: string }>
|
|
9
8
|
} ): Action {
|
|
9
|
+
if ( !template ) {
|
|
10
|
+
return () => undefined
|
|
11
|
+
}
|
|
12
|
+
|
|
10
13
|
return function execute( params ) {
|
|
11
14
|
const data = getData?.( params.context ) ?? params.context
|
|
12
15
|
|
|
@@ -15,7 +18,7 @@ export function renderTemplate( { fullpath, template, getData, write }: {
|
|
|
15
18
|
const renderedPath = params.renderer.renderString( { template: fullpath, data } )
|
|
16
19
|
|
|
17
20
|
if ( write ) {
|
|
18
|
-
return write( { content: renderedTemplate, destination: renderedPath } )
|
|
21
|
+
return write( { ...params, content: renderedTemplate, destination: renderedPath } )
|
|
19
22
|
}
|
|
20
23
|
}
|
|
21
24
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { assert } from "@std/assert"
|
|
2
1
|
import type { Action, Config } from "../types.ts"
|
|
3
2
|
import { prompt } from "./prompt.ts"
|
|
4
3
|
import { Renderer } from "../renderer.ts"
|
|
5
4
|
import { runGenerator } from "../runner.ts"
|
|
5
|
+
import assert from "node:assert"
|
|
6
6
|
|
|
7
7
|
export function selectGenerator( config: Config ): Action {
|
|
8
8
|
const choices = config.generators.map( ( { name, description } ) => ( { name, hint: description } ) )
|
package/actions/write.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
// TODO: get rid of `node:` imports and "del", "mkdirp" libraries
|
|
2
2
|
import { access, mkdir, rm, writeFile } from "node:fs/promises"
|
|
3
3
|
|
|
4
|
-
import { dirname } from "@std/path"
|
|
5
|
-
|
|
6
4
|
import type { Action } from "../types.ts"
|
|
5
|
+
import assert from "node:assert"
|
|
6
|
+
import { dirname } from "node:path"
|
|
7
7
|
|
|
8
8
|
// type WriteActionConfig = {
|
|
9
|
-
|
|
10
9
|
// data?: Record<string, unknown>
|
|
11
10
|
// destination: string
|
|
12
11
|
// writeMode?: "skip-if-exists" | "force"
|
|
@@ -16,34 +15,38 @@ import type { Action } from "../types.ts"
|
|
|
16
15
|
// |
|
|
17
16
|
// )
|
|
18
17
|
|
|
19
|
-
export type WriteActionConfig = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
mode
|
|
23
|
-
}
|
|
18
|
+
export type WriteActionConfig = { destination?: string; content?: string; mode?: "force" | "skip-if-exists" }
|
|
19
|
+
|
|
20
|
+
export function write(
|
|
21
|
+
{ destination, content, mode }: WriteActionConfig,
|
|
22
|
+
): Action<{ content?: string; destination?: string }> {
|
|
23
|
+
return async function execute( { content: content_, destination: destination_ } ) {
|
|
24
|
+
const dest = destination || destination_
|
|
25
|
+
const cntn = content || content_
|
|
26
|
+
|
|
27
|
+
assert( dest, "must provide `dest`" )
|
|
28
|
+
assert( cntn, "must provide `cntn`" )
|
|
24
29
|
|
|
25
|
-
|
|
26
|
-
return async function execute() {
|
|
27
|
-
await mkdir( dirname( config.destination ), { recursive: true } )
|
|
30
|
+
await mkdir( dirname( dest ), { recursive: true } )
|
|
28
31
|
|
|
29
|
-
let doesExist = await fileExists(
|
|
32
|
+
let doesExist = await fileExists( dest )
|
|
30
33
|
|
|
31
|
-
if ( doesExist &&
|
|
32
|
-
await rm(
|
|
34
|
+
if ( doesExist && mode === "force" ) {
|
|
35
|
+
await rm( dest, { recursive: true } )
|
|
33
36
|
doesExist = false
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
if ( doesExist &&
|
|
37
|
-
throw `File already exists\n -> ${
|
|
39
|
+
if ( doesExist && mode !== "skip-if-exists" ) {
|
|
40
|
+
throw `File already exists\n -> ${dest}`
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
if ( doesExist &&
|
|
41
|
-
console.info( `[SKIPPED] ${
|
|
43
|
+
if ( doesExist && mode === "skip-if-exists" ) {
|
|
44
|
+
console.info( `[SKIPPED] ${dest} (exists)` )
|
|
42
45
|
return
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
await writeFile(
|
|
46
|
-
}
|
|
48
|
+
await writeFile( dest, new TextEncoder().encode( cntn ) )
|
|
49
|
+
} satisfies Action<{ content?: string; destination?: string }>
|
|
47
50
|
|
|
48
51
|
// if(eager) {
|
|
49
52
|
// return execute()
|
package/deno.json
CHANGED
package/package.json
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeandmoney/jargal",
|
|
3
|
-
"version": "0.0.2-RC.
|
|
3
|
+
"version": "0.0.2-RC.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
|
-
|
|
7
|
-
},
|
|
8
|
-
"description": "Renderer",
|
|
9
|
-
"license": "MIT",
|
|
10
|
-
"author": "Code & Money Team",
|
|
11
|
-
"exports": {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
},
|
|
16
|
-
"fmt": {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
},
|
|
24
|
-
"devDependencies": {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
},
|
|
28
|
-
"dependencies": {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"description": "Renderer",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"author": "Code & Money Team",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./mod.ts",
|
|
13
|
+
"./types": "./types.ts",
|
|
14
|
+
"./actions": "./actions/exports.ts"
|
|
15
|
+
},
|
|
16
|
+
"fmt": {
|
|
17
|
+
"semiColons": false,
|
|
18
|
+
"trailingCommas": "onlyMultiLine",
|
|
19
|
+
"quoteProps": "asNeeded",
|
|
20
|
+
"indentWidth": 2,
|
|
21
|
+
"lineWidth": 120,
|
|
22
|
+
"spaceAround": true
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^24.7.0",
|
|
26
|
+
"bun-types": "^1.2.23"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"change-case": "^5.4.4",
|
|
30
|
+
"enquirer": "^2.4.1",
|
|
31
|
+
"es-toolkit": "^1.40.0",
|
|
32
|
+
"handlebars": "^4.7.8",
|
|
33
|
+
"title-case": "^4.3.2",
|
|
34
|
+
"valibot": "^1.1.0"
|
|
35
|
+
}
|
|
36
36
|
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import test from "node:test"
|
|
2
|
+
import assert from "node:assert"
|
|
3
|
+
import { join } from "node:path"
|
|
4
|
+
|
|
1
5
|
import { run } from "./runner.ts"
|
|
2
|
-
import { assert } from "@std/assert"
|
|
3
|
-
import { join } from "@std/path"
|
|
4
6
|
import { blank1, blank2 } from "./actions/blank.ts"
|
|
5
7
|
|
|
6
8
|
import type { Config, GeneratorConfig } from "./types.ts"
|
|
7
|
-
|
|
9
|
+
|
|
8
10
|
import { context } from "./actions/context.ts"
|
|
11
|
+
import { loadTemplates } from "./actions/load-templates.ts"
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
test("simple", async () => {
|
|
11
14
|
const simple: GeneratorConfig = {
|
|
12
15
|
name: "simple",
|
|
13
16
|
description: "description",
|
|
@@ -16,7 +19,7 @@ Deno.test("simple", async () => {
|
|
|
16
19
|
blank2,
|
|
17
20
|
context( () => ( { kek: Math.random() } ) ),
|
|
18
21
|
console.log,
|
|
19
|
-
loadTemplates( join(
|
|
22
|
+
loadTemplates( join( process.cwd(), "actions" ) ),
|
|
20
23
|
],
|
|
21
24
|
}
|
|
22
25
|
|
package/runner.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { assert } from "@std/assert"
|
|
2
1
|
import { Renderer } from "./renderer.ts"
|
|
3
2
|
import * as v from "valibot"
|
|
4
|
-
|
|
5
3
|
import type { Action, Config, ExecuteActionParams, GeneratorParams } from "./types.ts"
|
|
6
|
-
import { selectGenerator } from "./actions/
|
|
4
|
+
import { selectGenerator } from "./actions/select-generator.ts"
|
|
5
|
+
import assert from "node:assert"
|
|
7
6
|
|
|
8
7
|
export async function runGenerator( { context, generator, renderer }: GeneratorParams ): Promise<void> {
|
|
9
8
|
assert( generator )
|
|
@@ -19,10 +18,18 @@ export async function executeAction(
|
|
|
19
18
|
): Promise<void | Action | Action[]> {
|
|
20
19
|
if ( Array.isArray( action ) ) {
|
|
21
20
|
for ( const action_ of action ) {
|
|
22
|
-
|
|
21
|
+
const executed = await action_( { context, renderer } )
|
|
22
|
+
if ( !executed ) {
|
|
23
|
+
continue
|
|
24
|
+
}
|
|
25
|
+
await execRecursive( executed, { context, renderer } )
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
|
|
29
|
+
if ( typeof action !== "function" ) {
|
|
30
|
+
return undefined
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
const executed = await action( { context, renderer } )
|
|
27
34
|
|
|
28
35
|
if ( !executed ) {
|
|
@@ -37,7 +44,7 @@ async function execRecursive(
|
|
|
37
44
|
{ context, renderer }: Omit<ExecuteActionParams, "action">,
|
|
38
45
|
): Promise<Action | Action[] | void> {
|
|
39
46
|
if ( Array.isArray( executed ) ) {
|
|
40
|
-
const executionResults:
|
|
47
|
+
const executionResults: Action[] = []
|
|
41
48
|
|
|
42
49
|
for ( const action of executed ) {
|
|
43
50
|
const result = await executeAction( { action, context, renderer } )
|
|
@@ -92,9 +99,7 @@ export async function run( config_: Config ): Promise<void> {
|
|
|
92
99
|
renderer: new Renderer(),
|
|
93
100
|
generator: {
|
|
94
101
|
name: "select",
|
|
95
|
-
actions: [
|
|
96
|
-
selectGenerator( config ),
|
|
97
|
-
],
|
|
102
|
+
actions: [ selectGenerator( config ) ],
|
|
98
103
|
},
|
|
99
104
|
} )
|
|
100
105
|
}
|
package/types.ts
CHANGED
|
@@ -48,7 +48,9 @@ export type HelperFn = ( str: string ) => string
|
|
|
48
48
|
|
|
49
49
|
export interface TextHelpers extends Record<string, HelperFn> {}
|
|
50
50
|
|
|
51
|
-
export type Action
|
|
51
|
+
export type Action<T extends object = {}> = (
|
|
52
|
+
params: ActionParams & T,
|
|
53
|
+
) => void | Action | Action[] | Promise<void | Action | Action[]>
|
|
52
54
|
|
|
53
55
|
export interface ActionHooksFailures {
|
|
54
56
|
path: string
|
|
File without changes
|