Skip to content

Commit

Permalink
feat: implementing advanced command #wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ipetinate committed May 21, 2024
1 parent cb1e91d commit c92e8e6
Show file tree
Hide file tree
Showing 10 changed files with 468 additions and 15 deletions.
18 changes: 18 additions & 0 deletions .clingon/presets/generator.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"framework": null,
"cssFramework": "css_vanilla",
"testFramework": "jest",
"version": null,
"name": "scaffold-template",
"resourcePath": "src/generators",
"testPath": "src/generators",
"storyPath": null,
"testPostfix": "test",
"storyPostfix": "stories",
"type": "function",
"typescript": false,
"withStory": false,
"withTest": true,
"withTestingLibrary": false,
"folderWrapper": false
}
18 changes: 18 additions & 0 deletions .clingon/presets/util.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"framework": null,
"cssFramework": "css_vanilla",
"testFramework": "jest",
"version": null,
"name": "scaffold-template",
"resourcePath": "src/utils",
"testPath": "src/utils",
"storyPath": null,
"testPostfix": "test",
"storyPostfix": "stories",
"type": "function",
"typescript": false,
"withStory": false,
"withTest": true,
"withTestingLibrary": false,
"folderWrapper": false
}
58 changes: 45 additions & 13 deletions src/actions/scaffold.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,52 @@
import { readFileContent } from '../utils/file.js'
import { parse as parseYaml } from 'yaml'
import { join } from 'node:path'

export function scaffoldAction(name, options) {
const template = getTemplateFomMetaFile(options.template)
}
import { buildFromTemplate } from '../generators/scaffold-template.js'

import {
getTemplateFromMetaFile,
validateTemplate
} from '../utils/scaffold-action.js'

/**
* Build resources from local custom templates
*
* @typedef {"template"} Options
*
* @param {string} name
* @param {Record<Options, string>} options
*/

export function getTemplateFomMetaFile() {
try {
const path = join(process.cwd(), '.clingon', 'templates', 'meta.yaml')
export async function scaffoldAction(name, options) {
/**
* Templates folder path
*/
const basePath = join(process.cwd(), '.clingon', 'templates')

const fileContent = readFileContent(path)
/**
* Templates from meta file
*/
const template = getTemplateFromMetaFile(options.template)

/**
* Template already be validated and flow can continue
*/
const alreadyOkContinue = validateTemplate(template)

if (!alreadyOkContinue) {
throw new Error(
'Template has many errors, please, review your meta at: ',
basePath
)
}

const parsedYamlFileContent = yaml
/**
* Resources already be created
*/
const created = await buildFromTemplate(name, template)

return parsedYamlFileContent
} catch (error) {
console.error(error)
if (created) {
console.info('Success')
} else {
console.info('Fail')
}
}
136 changes: 136 additions & 0 deletions src/generators/scaffold-template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { compose } from '../utils/compose.js'
import { convertCase, splitPathString } from '../utils/string.js'
import { readFileContent } from '../utils/file.js'
import { replaceContentFromSideResource } from '../utils/scaffold-action.js'
import { checkDirectoriesTree } from '../utils/directory.js'

/**
* @typedef {Record<keyof Omit<import('../types').CustomTemplate, "folderWrapper" | "identifier">, string>} TemplatesContent
*
* @typedef {{name: string, template: import('../types').CustomTemplate, templatesContent: TemplatesContent}} CommomReturn
*/

/**
* Build resources from template
*
* @param {string} name Resource name from arguments
* @param {import("../types").CustomTemplate} template Local template from meta file
* @returns {Promise<boolean>}
*/
export async function buildFromTemplate(name, template) {
const result = compose(
getTemplatesData(name, template),
handleTemplateReplacements,
checkPaths,
createResources
)

return result
}

/**
* Get templates from local dir
*
* @param {string} name Resource name from arguments
* @param {import('../types').CustomTemplate} template Template data from meta file
*
* @returns {CommomReturn}
*/
function getTemplatesData(name, template) {
return () => {
/**
* @type {TemplatesContent}
*/
const templatesContent = {
resource: readFileContent(template.resource.template)
}

if (template.test) {
templatesContent.test = readFileContent(template.test.template)
}

if (template.story) {
templatesContent.story = readFileContent(template.story.template)
}

return { name, template, templatesContent }
}
}

/**
* Replace text occurrences inside template
*
* @param {ReturnType<typeof getTemplatesData>} param0 - Template data and templates content
*/
function handleTemplateReplacements({ name, template, templatesContent }) {
name = convertCase('PascalCase', name)

templatesContent.resource = templatesContent.resource.replace(
/ResourceName/g,
name
)

if (templatesContent.story) {
templatesContent.story = replaceContentFromSideResource(
name,
templatesContent.story,
template
)
}

if (templatesContent.test) {
templatesContent.test = replaceContentFromSideResource(
name,
templatesContent.test,
template
)
}

return { name, template, templatesContent }
}

/**
* Check templates path and ask if not exists
*
* @param {ReturnType<typeof handleTemplateReplacements>} param0 Template data from meta file
*/
function checkPaths({ name, template, templatesContent }) {
const targets = {
resource: false,
test: false,
story: false
}

targets.resource = checkDirectoriesTree(
splitPathString(template.resource.path)
)

if (templatesContent.test) {
targets.test = checkDirectoriesTree(splitPathString(template.test.path))
}

if (templatesContent.story) {
targets.story = checkDirectoriesTree(splitPathString(template.story.path))
}

return { name, template, templatesContent, targets }
}

/**
*
* @param {ReturnType<typeof checkPaths>} param0 Template data from meta file
* @returns {boolean}
*/
function createResources({ name, targets, template, templatesContent }) {
if (targets.resource) {
// TODO: generate file
}
if (targets.test) {
// TODO: generate file
}
if (targets.style) {
// TODO: generate file
}

return true
}
13 changes: 13 additions & 0 deletions src/generators/scaffold-template.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import assert from 'node:assert/strict'

import { describe, it } from 'node:test'

import { scaffoldTemplate } from './scaffold-template'

describe('scaffoldTemplate', () => {
it('should works properly', () => {
const result = scaffoldTemplate()

assert.strictEqual(result, true)
})
})
29 changes: 29 additions & 0 deletions src/schemas/custom-template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Define the type map for TemplateResource
*
* @type {Record<keyof import("../types").TemplateResource, import("../types").Primitives>}
*/
export const templateResourceTypeMap = {
index: 'boolean',
path: 'string',
template: 'string'
}

/**
* Define the type map for CustomTemplate
*
* @type {Record<keyof import("../types").CustomTemplate, import("../types").Primitives | typeof templateResourceTypeMap> }
*/
export const customTemplateTypeMap = {
identifier: 'string',
folderWrapper: 'boolean',
resource: templateResourceTypeMap,
test: {
path: 'string',
template: 'string'
},
story: {
path: 'string',
template: 'string'
}
}
30 changes: 28 additions & 2 deletions src/types.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { ResourceTypeEnum } from 'enums/resource-type.js'
import { FileExtensionEnum } from 'enums/file-extension.js'
import { FrameworkEnum, TestFrameworkEnum, CssFrameworkEnum } from 'enums/frameworks.js'
import { StoryPostfixEnum, TestPostfixEnum, StylePostfixEnum } from 'enums/postfixes.js'
import {
FrameworkEnum,
TestFrameworkEnum,
CssFrameworkEnum
} from 'enums/frameworks.js'
import {
StoryPostfixEnum,
TestPostfixEnum,
StylePostfixEnum
} from 'enums/postfixes.js'

/**
* @typedef {keyof typeof ResourceTypeEnum} Resource - Resource type
Expand Down Expand Up @@ -83,6 +91,24 @@ import { StoryPostfixEnum, TestPostfixEnum, StylePostfixEnum } from 'enums/postf
* @typedef {"options" | "setup"} VueApi - Vue api template syntax
*
* @typedef {"class" | "functional"} ReactComponentVariant - React component type variant (class or functional)
*
* @typedef {{
* index?: boolean
* path: string
* template: string
* }} TemplateResource - Template resource definition
*
* @typedef {{
* identifier: string
* folderWrapper: boolean
* resource: TemplateResource
* test?: Omit<TemplateResource, "index">
* story?: Omit<TemplateResource, "index">
* }} CustomTemplate - Custom template from meta file
*
* @typedef {"bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"} Primitives - JS Primities
*/

typeof 1 == ''

export default {}
Loading

0 comments on commit c92e8e6

Please sign in to comment.