@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.
@@ -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 "./validate_answers.ts"
7
- export { loadTemplates } from "./load_templates.ts"
8
- export { renderTemplate } from "./render_template.ts"
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 { promises as fs } from "node:fs"
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 fs.readFile( path.resolve( templatesPath, fullPath ) )
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 fs.readdir( dir, { withFileTypes: true } )
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?: ( config: WriteActionConfig ) => Action
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
- content: string
21
- destination: string
22
- mode?: "force" | "skip-if-exists"
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
- export function write( config: WriteActionConfig ): Action {
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( config.destination )
32
+ let doesExist = await fileExists( dest )
30
33
 
31
- if ( doesExist && config.mode === "force" ) {
32
- await rm( config.destination, { recursive: true } )
34
+ if ( doesExist && mode === "force" ) {
35
+ await rm( dest, { recursive: true } )
33
36
  doesExist = false
34
37
  }
35
38
 
36
- if ( doesExist && config.mode !== "skip-if-exists" ) {
37
- throw `File already exists\n -> ${config.destination}`
39
+ if ( doesExist && mode !== "skip-if-exists" ) {
40
+ throw `File already exists\n -> ${dest}`
38
41
  }
39
42
 
40
- if ( doesExist && config.mode === "skip-if-exists" ) {
41
- console.info( `[SKIPPED] ${config.destination} (exists)` )
43
+ if ( doesExist && mode === "skip-if-exists" ) {
44
+ console.info( `[SKIPPED] ${dest} (exists)` )
42
45
  return
43
46
  }
44
47
 
45
- await writeFile( config.destination, new TextEncoder().encode( config.content ) )
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeandmoney/jargal",
3
- "version": "0.0.2-RC.5",
3
+ "version": "0.0.2-RC.6",
4
4
  "description": "Renderer",
5
5
  "license": "MIT",
6
6
  "author": "Code & Money Team",
package/package.json CHANGED
@@ -1,36 +1,36 @@
1
1
  {
2
2
  "name": "@codeandmoney/jargal",
3
- "version": "0.0.2-RC.5",
3
+ "version": "0.0.2-RC.6",
4
4
  "private": false,
5
5
  "publishConfig": {
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
- }
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
- import { loadTemplates } from "./actions/load_templates.ts"
9
+
8
10
  import { context } from "./actions/context.ts"
11
+ import { loadTemplates } from "./actions/load-templates.ts"
9
12
 
10
- Deno.test("simple", async () => {
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( Deno.cwd(), "actions" ) ),
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/select_generator.ts"
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
- return await executeAction( { action: action_, context, renderer } )
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: (Action)[] = []
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 = ( params: ActionParams ) => void | Action | Action[] | Promise<void | Action | 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