import nunjucks from 'nunjucks'; import { ICommand, CommandAction } from './model'; export const VER = '0.2.55'; // TODO: get this from package.json. // const TelemetryReporter = require('vscode-extension-telemetry'); // const extensionId = 'coddx-alpha'; // const extensionVersion = '0.2.11'; // const key = ''; // export const telemetry = new TelemetryReporter(extensionId, extensionVersion, key); // TODO: this crashed! export interface FilesInterface { checked?: boolean; fileMarker?: string; fileeName?: string; fileContent?: string; } export const FILE_SEPARATOR = '--->>'; export const DefaultTemplateString = `// -------------->> {{fileName}}.tsx // created time: {{YYYY}}-{{MM}}-{{DD}} {{HH}}:{{mm}} import * as React from 'react'; import './{{fileName}}.css'; export default class {{fileName}} extends React.Component { render() { return ( <div> {/* ...code goes here... */} </div> ) } } // -------------->> {{fileName}}.css .main {} // -------------->> __test__/{{fileName}}.test.tsx import * as React from 'react'; it('{{fileName}} - render', () => { // render(<{{fileName}} />); // expect(...); }); `; const getBuiltInParams = () => { const fd = formatDate(new Date()); return { YYYY: fd.year, MM: fd.month, DD: fd.day, HH: fd.hours24, mm: fd.minutes, ss: fd.seconds }; }; // format to: yyy-mm-dd export function formatDate(d: Date) { let month = '' + (d.getMonth() + 1); let day = '' + d.getDate(); const year = d.getFullYear(); if (month.length < 2) month = '0' + month; if (day.length < 2) day = '0' + day; return { year, month, day, hours24: d.getHours(), minutes: d.getMinutes(), seconds: d.getSeconds(), yyyymmdd: [year, month, day].join('-') }; } export function parseJsonString(jsonString: string) { if (!jsonString || !jsonString.trim()) { return {}; } let useParams = {}; try { useParams = JSON.parse(jsonString.trim()); } catch {} return useParams; } export function jsonClone(obj: any) { if (!obj) { return obj; // null or undefined } return JSON.parse(JSON.stringify(obj)); } export function deepFind(obj: any, path: string, defaultValue: any) { const travel = regexp => String.prototype.split .call(path, regexp) .filter(Boolean) .reduce((res, key) => (res !== null && res !== undefined ? res[key] : res), obj); const result = travel(/[,[\]]+?/) || travel(/[,[\].]+?/); return result === undefined || result === obj ? defaultValue : result; } export function nunjucksRender(str: string, data: any): string { const tmpl = nunjucks.compile(str); return tmpl.render({ ...getBuiltInParams(), ...data }); } // from content string => parse to get file contents & put in "files" object {} export function getTemplateItems(content: string, params: any = {}, existingFiles: any = {}): FilesInterface { const lines = content.split('\n'); const output: FilesInterface = {}; let fileContent = ''; let lastKey = ''; lines.forEach(line => { if (line.indexOf(FILE_SEPARATOR) >= 0) { // when seeing a new file separator => set the accumulated "fileContent" string for the lastKey: if (lastKey) { output[lastKey].fileContent = nunjucksRender(fileContent, params).trim(); fileContent = ''; // reset fileContent, prepare for the next file. } const arr = line.split(FILE_SEPARATOR); const itemKey = arr[arr.length - 1].trim(); const existingItem = existingFiles[itemKey] || {}; const fileName = nunjucksRender(itemKey, params).trim(); output[itemKey] = { checked: existingItem.checked !== undefined ? existingItem.checked : true, fileMarker: line.replace(itemKey, fileName), fileName, fileContent }; lastKey = itemKey; } else { if (output[lastKey] && output[lastKey].checked === true) { fileContent += line + '\n'; } } }); if (lastKey) { output[lastKey].fileContent = nunjucksRender(fileContent, params).trim(); } return output; } export const sendCommand = (vscode: any, action: CommandAction, dataStr: string) => { let command: ICommand = { action: action, content: { name: '', description: dataStr } }; if (vscode.postMessage) { vscode.postMessage(command); } }; export function getVscodeHelper(vscode: any) { return { showMessage: (msg: string) => vscode.postMessage({ action: CommandAction.ShowMessage, content: { name: '', description: msg } }), saveList: (dataStr: string) => { let command: ICommand = { action: CommandAction.Save, content: { name: '', description: dataStr } }; if (vscode.postMessage) { vscode.postMessage(command); } } }; } // In VSCode, "btoa" function is not available (?) => use this: // A helper that returns Base64 characters and their indices. // const chars = { // ascii: function() { // return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; // }, // indices: function() { // if (!this.cache) { // this.cache = {}; // var ascii = chars.ascii(); // for (var c = 0; c < ascii.length; c++) { // var chr = ascii[c]; // this.cache[chr] = c; // } // } // return this.cache; // } // }; // const toBase64 = function(data) { // var ascii = chars.ascii(), // len = data.length - 1, // i = -1, // b64 = ''; // while (i < len) { // var code = (data.charCodeAt(++i) << 16) | (data.charCodeAt(++i) << 8) | data.charCodeAt(++i); // b64 += ascii[(code >>> 18) & 63] + ascii[(code >>> 12) & 63] + ascii[(code >>> 6) & 63] + ascii[code & 63]; // } // var pads = data.length % 3; // if (pads > 0) { // b64 = b64.slice(0, pads - 3); // while (b64.length % 4 !== 0) { // b64 += '='; // } // } // return b64; // };