lodash#template TypeScript Examples

The following examples show how to use lodash#template. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: api-client-generator.ts    From selling-partner-api-sdk with MIT License 6 votes vote down vote up
function generateExportStatements(project: Project, apiModels: APIModel[]) {
  log.info(`Starting exporting api clients`)

  const compileExportStatement = template(`export * from './<%= apiClientFileName %>'`)
  const exportStatements = apiModels.map((apiModel) =>
    compileExportStatement({
      apiClientFileName: generateAPIClientFileName(apiModel),
    }),
  )
  project.createSourceFile('src/api-clients/index.ts', exportStatements.join('\n'), {
    overwrite: true,
  })
  log.info(`Finished exporting api clients`)
}
Example #2
Source File: api-client-generator.ts    From selling-partner-api-sdk with MIT License 6 votes vote down vote up
export function generateAPIClients(apiModels: APIModel[]): void {
  const compileAPIClient = template(apiClientTemplate)
  const project = new Project({
    tsConfigFilePath: TS_CONFIG_FILE_PATH,
    libFolderPath: TS_LIB_FOLDER_PATH,
  })

  for (const apiModel of apiModels) {
    const apiClientFileName = generateAPIClientFileName(apiModel)
    generateAPIClient(
      project,
      compileAPIClient,
      apiModel,
      apiClientFileName,
      generateAPIClientClassname(apiClientFileName),
    )
  }

  generateExportStatements(project, apiModels)
  project.saveSync()
}
Example #3
Source File: tpl-lodash.ts    From brick-design with MIT License 6 votes vote down vote up
function lodashCompile(str: string, data: object) {
  try {
    const filters = getFilters();
    const finnalImports = {
      ...filters,
      formatTimeStamp: filters.date,
      formatNumber: filters.number,
      defaultValue: filters.defaut,
      ...imports,
    };
    delete finnalImports.default; // default 是个关键字,不能 imports 到 lodash 里面去。
    const fn =
      EVAL_CACHE[str] ||
      (EVAL_CACHE[str] = template(str, {
        imports: finnalImports,
        variable: 'data',
      }));

    return fn.call(data, data);
  } catch (e) {
    return `<span class="text-danger">${e.message}</span>`;
  }
}
Example #4
Source File: index.ts    From semantic-release-replace-plugin with Apache License 2.0 6 votes vote down vote up
export async function prepare(
  PluginConfig: PluginConfig,
  context: Context
): Promise<void> {
  for (const replacement of PluginConfig.replacements) {
    let { results } = replacement;

    delete replacement.results;

    const replaceInFileConfig = replacement as ReplaceInFileConfig;

    replaceInFileConfig.to =
      typeof replacement.to === "function"
        ? replacement.to
        : template(replacement.to)({ ...context });
    replaceInFileConfig.from = new RegExp(replacement.from, "gm");

    let actual = await replaceInFile(replaceInFileConfig);

    if (results) {
      results = results.sort();
      actual = actual.sort();

      if (!isEqual(actual.sort(), results.sort())) {
        throw new Error(
          `Expected match not found!\n${diffDefault(actual, results)}`
        );
      }
    }
  }
}
Example #5
Source File: ui.ts    From js-examples with MIT License 6 votes vote down vote up
displayIdentity = (publicKey: string) => {
  const shortId = publicKey.substr(publicKey.length - 11, 10)
  const outputElement = document.getElementById('publicKey');
  if (outputElement) {
    var compiled = template(`
      <strong>identity:</strong> <%- shortId %>
    `.trim());
    outputElement.innerHTML = compiled({
      shortId,
    });
  }
}
Example #6
Source File: ui.ts    From js-examples with MIT License 6 votes vote down vote up
displayAvatar = (identity: string) => {
  const outputElement = document.getElementById('identity');
  if (outputElement) {
    var compiled = template(`
      <svg width="80" height="80" data-jdenticon-value="<%- identity %>"></svg>
    `.trim());
    outputElement.innerHTML = compiled({
      identity,
    });
    /** trigger rendering */
    jdenticon();
  }
}
Example #7
Source File: Upload.tsx    From gio-design with Apache License 2.0 4 votes vote down vote up
Upload: React.FC<IUploadProps> = ({
  file: uploadedFile,
  fileList,
  defaultFileList,
  successBorder = false,
  style,
  prefixCls: customPrefixCls,
  className,
  disabled,
  type = 'button',
  inputUploadType = 'url',
  triggerProps,
  action = '.',
  beforeUpload,
  onStart,
  onProgress,
  onError,
  onSuccess,
  onChange,
  onRemove,
  openFileDialogOnClick = true,
  children,
  placeholderImg,
  iconSize,
  maxCount = 1,
  directory,
  multiple,
  showUploadList = true,
  ...restProps
}: IUploadProps) => {
  const [file, setFile] = useState<IUploadFile>(getEmptyFileObj(uploadedFile));
  const [showAlert, setAlert] = useState(false);
  // 要上传的文件列表
  const [uploadFileList, setUploadFileList] = useControlledState<IRcFile[]>(
    (defaultFileList?.slice(0, maxCount) as IRcFile[]) || [],
    {
      value: fileList?.slice(0, maxCount) as IRcFile[],
    }
  );
  // 已经上传了的文件数量
  const [finish, setFinish] = useState(Math.min(uploadFileList.length, maxCount));
  // 控制dragTrigger是否disabled
  const [uploadDisabled, setUploadDisabled] = useState(disabled);

  const locale = useLocale('Upload');
  const { defaultErrorMessage, picLimit, fileLimit }: { [key: string]: string } = {
    ...defaultLocale,
    ...locale,
  };

  useEffect(() => {
    setFile(getEmptyFileObj(uploadedFile));
  }, [uploadedFile]);

  useEffect(() => {
    if (Number(defaultFileList?.length) >= maxCount || Number(fileList?.length) >= maxCount) {
      setUploadDisabled(true);
    }
  }, [defaultFileList, fileList, maxCount]);

  const rcUploadRef = useRef(null);
  const prefixCls = usePrefixCls('upload', customPrefixCls);

  const rootCls = classnames(className, prefixCls, {
    [`${prefixCls}--disabled`]: disabled || (type === 'drag' && uploadDisabled),
    [`${prefixCls}--error`]: file.status === STATUS_ERROR,
    [`${prefixCls}--success`]: file.status === STATUS_SUCCESS && !successBorder,
    [`${prefixCls}--success-border`]: file.status === STATUS_SUCCESS && successBorder,
    [`${prefixCls}-drag-container`]: type === 'drag',
  });
  const Trigger = triggerMap[type];

  const onFileChange = (_file: IUploadFile, mergedFileList: IUploadFile[]) => {
    let cloneList = [...mergedFileList];

    // 选择的文件超出最大上传文件数量限制
    if (cloneList.length >= maxCount && (directory || multiple)) {
      setUploadDisabled(true);
      cloneList.length > maxCount && setAlert(true);
      cloneList = cloneList.slice(0, maxCount);
    }

    const finishCount = cloneList.filter(
      (item: IUploadFile) => item.status === 'success' || item.status === 'error'
    ).length;

    setFinish(Math.min(finishCount, cloneList.length));
    setUploadFileList(cloneList as IRcFile[]);

    onChange?.(_file, cloneList);
  };

  const handleSingleBeforeUpload = (fileBeforeUpload: IRcFile, fileListArgs: IRcFile[]) =>
    beforeUpload?.(fileBeforeUpload, fileListArgs);

  const handleMultipleBeforeUpload = (fileBeforeUpload: IRcFile, fileListArgs: IRcFile[]) => {
    const mergeFileList = [...uploadFileList, ...fileListArgs];
    // 如果选择的文件数量超出最大限制,进行截断
    const fileIndex = mergeFileList.findIndex((item) => item.uid === fileBeforeUpload.uid);
    if (fileIndex >= maxCount) {
      return false;
    }

    onFileChange(fileBeforeUpload, mergeFileList);

    return beforeUpload?.(fileBeforeUpload, fileListArgs);
  };

  const handleStart = (fileOnStart: IRcFile) => {
    const uploadFile: IUploadFile = {
      ...fileToObject(fileOnStart),
      status: STATUS_UPLOADING,
    };

    const updatedFileList = updateFileList(uploadFile, uploadFileList);
    onFileChange(uploadFile, updatedFileList);

    setFile(uploadFile);
    onStart?.(uploadFile, updatedFileList);
  };

  const handleProgress = (step: IProgress, fileOnProgress: IRcFile) => {
    if (!getFileItem(fileOnProgress, uploadFileList) && (directory || multiple)) {
      return;
    }

    const progressFile: IUploadFile = {
      ...fileToObject(fileOnProgress),
      status: STATUS_UPLOADING,
      percent: step.percent,
    };

    const updatedFileList = updateFileList(progressFile, uploadFileList);
    onFileChange(progressFile, updatedFileList);

    setFile(progressFile);
    onProgress?.(step, fileOnProgress, updatedFileList as IRcFile[]);
  };

  const handleSuccess = async (response: Record<string, unknown>, fileOnSuccess: IRcFile) => {
    if (!getFileItem(fileOnSuccess, uploadFileList) && (directory || multiple)) {
      return;
    }

    let dataUrl = '';
    const uploadFile: IUploadFile = {
      ...fileToObject(fileOnSuccess),
      response,
      status: STATUS_SUCCESS,
      percent: 100,
    };

    try {
      if (fileOnSuccess.type?.startsWith('image/')) {
        dataUrl = await imageFile2DataUrl(fileOnSuccess);
        uploadFile.dataUrl = dataUrl;
      }
    } catch (error) {
      console.error(error);
    }

    const updatedFileList = updateFileList(uploadFile, uploadFileList);

    onSuccess?.(response, uploadFile, updatedFileList);
    setFile(uploadFile);
    onFileChange(uploadFile, updatedFileList);
  };

  const handleError = (error: Error, response: any, fileOnError: IRcFile) => {
    if (!getFileItem(fileOnError, uploadFileList) && (directory || multiple)) {
      return;
    }

    const errorFile: IUploadFile = {
      ...fileToObject(fileOnError),
      error,
      response,
      status: STATUS_ERROR,
      errorMessage: defaultErrorMessage,
    };

    const updatedFileList = updateFileList(errorFile, uploadFileList);
    onFileChange(errorFile, updatedFileList);

    onError?.(error, errorFile, updatedFileList);

    setFile(type !== 'drag' ? getEmptyFileObj(uploadedFile) : errorFile);
  };

  const handleRemove = (_file: IUploadFile) => {
    Promise.resolve(typeof onRemove === 'function' ? onRemove(_file) : onRemove).then((res) => {
      // 使用者返回了 false,阻止删除操作
      if (res === false) {
        return;
      }

      const removedFileList = removeFileItem(_file, uploadFileList);

      removedFileList.length < maxCount && setAlert(false);
      removedFileList.length < maxCount && setUploadDisabled(false);

      onFileChange(_file, removedFileList);

      if (file.dataUrl === uploadedFile?.dataUrl) {
        setFile({
          uid: '',
          size: 0,
          name: '本地上传',
          type: '$empty-file',
          status: STATUS_NOT_YET,
          dataUrl: '',
        });
      } else {
        setFile(getEmptyFileObj(uploadedFile));
      }
    });
  };

  const handleInputUpload = async (uploadType: TInputUploadType = 'url', url: string) => {
    const uploadFile = {
      ...file,
      type: 'image',
      name: 'web-image',
    };
    if (uploadType === 'url') {
      uploadFile.dataUrl = url;
      uploadFile.status = STATUS_SUCCESS;
      setFile(uploadFile);
      onSuccess?.({}, uploadFile, uploadFileList);
    } else {
      try {
        uploadFile.status = STATUS_UPLOADING;
        setFile(uploadFile);
        const { originFile } = await fetchImageFileFromUrl(url);
        const request = restProps.customRequest || xhrRequest;
        let ac: string;
        if (typeof action === 'function') {
          ac = await action(originFile);
        } else {
          ac = action as string;
        }

        let data: Record<string, string | Blob>;
        if (typeof restProps.data === 'function') {
          data = restProps.data(uploadFile);
        } else {
          data = restProps.data ?? {};
        }
        request({
          action: ac,
          filename: restProps.name ?? 'file',
          data,
          file: originFile,
          headers: restProps.headers ?? {},
          withCredentials: restProps.withCredentials ?? false,
          method: restProps.method || 'post',
          onProgress: (e: IProgress) => handleProgress(e, originFile),
          onSuccess: (res: Record<string, unknown>) => handleSuccess(res, originFile),
          onError: (err: Error, res: Record<string, unknown>) => handleError(err, res, originFile),
        });
      } catch (error) {
        setFile({ ...file, error });
        onError?.(error, file, uploadFileList);
      }
    }
  };

  const showBeyondAlert = () =>
    showAlert &&
    maxCount && (
      <Alert
        type="error"
        message={
          isOnlyAcceptImg(restProps.accept)
            ? template(picLimit, { interpolate: /{([\s\S]+?)}/g })({ maxCount })
            : template(fileLimit, { interpolate: /{([\s\S]+?)}/g })({ maxCount })
        }
        showIcon
        closeable
        onClose={() => setAlert(false)}
      />
    );

  const renderUploadList = () =>
    showUploadList && (directory || multiple) ? (
      <UploadList items={uploadFileList} onRemove={handleRemove} accept={restProps.accept} />
    ) : null;

  const rcUploadProps = {
    ...restProps,
    disabled: disabled || (type === 'drag' && uploadDisabled),
    prefixCls: type === 'drag' ? `${prefixCls}-drag-container` : prefixCls,
    action,
    directory,
    multiple,
    beforeUpload: directory || multiple ? handleMultipleBeforeUpload : handleSingleBeforeUpload,
    onStart: handleStart,
    onProgress: handleProgress,
    onSuccess: handleSuccess,
    onError: handleError,
    openFileDialogOnClick: type === 'input' ? false : openFileDialogOnClick,
  };

  const triggerComponentProps: ITriggerProps = {
    triggerProps: {
      ...triggerProps,
    },
    file,
    items: uploadFileList,
    finishCount: finish,
    accept: restProps.accept,
    inputUploadType,
    setFile,
    onRemove: handleRemove,
    onReSelect: restProps.onReSelect,
    onInputUpload: handleInputUpload,
    placeholderImg,
    iconSize,
    directory,
    multiple,
    maxCount,
    disabled: disabled || (type === 'drag' && uploadDisabled),
    dragStyle: restProps.dragStyle,
  };

  if (type === 'drag') {
    return (
      <UploadPrefixClsContext.Provider value={prefixCls}>
        <div className={rootCls} style={style}>
          {showBeyondAlert()}
          <RcUpload data-testid="upload" {...rcUploadProps} ref={rcUploadRef}>
            <Trigger {...triggerComponentProps}>{children}</Trigger>
          </RcUpload>
          {renderUploadList()}
        </div>
      </UploadPrefixClsContext.Provider>
    );
  }

  return (
    <UploadPrefixClsContext.Provider value={prefixCls}>
      <div className={rootCls} style={style}>
        <RcUpload data-testid="upload" {...rcUploadProps} ref={rcUploadRef}>
          <Trigger {...triggerComponentProps}>{children}</Trigger>
        </RcUpload>
      </div>
    </UploadPrefixClsContext.Provider>
  );
}
Example #8
Source File: DragTrigger.tsx    From gio-design with Apache License 2.0 4 votes vote down vote up
DragTrigger: React.FC<ITriggerProps> = ({
  triggerProps,
  file,
  accept,
  onRemove,
  iconSize,
  items,
  finishCount = 0,
  disabled,
  directory,
  multiple,
  maxCount,
  dragStyle,
  onReSelect,
}: ITriggerProps) => {
  const [dragState, setDragState] = useState('');
  const prefixCls = useContext(UploadPrefixClsContext);
  const cls = classnames(triggerProps?.className, `${prefixCls}__drag`, {
    [`${prefixCls}__drag--hover`]: dragState === 'dragover',
  });
  const placeholderCls = classnames(`${prefixCls}__drag-placeholder`);
  const progressCls = classnames(`${prefixCls}__drag-progress`);

  const locale = useLocale('Upload');

  const {
    disabledPic,
    disabledFile,
    dragPic,
    dragFile,
    uploading,
    picPending,
    filePending,
  }: { [key: string]: string } = {
    ...defaultLocale,
    ...locale,
  };

  const handleDrag = (e: React.DragEvent<HTMLDivElement>) => setDragState(e.type);

  const [currentWidth, currentHeight] = Array.isArray(iconSize) ? iconSize : [iconSize, iconSize];

  const fileListLength = items?.length ?? 0;

  const renderDisabledPlaceholder = () =>
    isOnlyAcceptImg(accept) ? (
      <>
        <DisabledPictureSVG style={{ width: currentWidth, height: currentHeight }} />
        <div>{template(disabledPic, { interpolate: /{([\s\S]+?)}/g })({ count: finishCount })}</div>
      </>
    ) : (
      <>
        <DisabledFolderSVG style={{ width: currentWidth, height: currentHeight }} />
        <div>{template(disabledFile, { interpolate: /{([\s\S]+?)}/g })({ count: finishCount })}</div>
      </>
    );

  const renderPlaceholder = () =>
    isOnlyAcceptImg(accept) ? (
      <>
        <PictureSVG style={{ width: currentWidth, height: currentHeight }} />
        <div>{template(dragPic, { interpolate: /{([\s\S]+?)}/g })({ count: finishCount, maxCount })}</div>
      </>
    ) : (
      <>
        <FolderSVG style={{ width: currentWidth, height: currentHeight }} />
        <div>{template(dragFile, { interpolate: /{([\s\S]+?)}/g })({ count: finishCount, maxCount })}</div>
      </>
    );

  // 单个文件上传渲染
  const renderSingleUpload = () => (
    <div className={cls} onDrop={handleDrag} onDragOver={handleDrag} onDragLeave={handleDrag} style={dragStyle}>
      {'percent' in file && file.status === STATUS_UPLOADING ? (
        <div className={`${prefixCls}__drag-container`}>
          <Progress
            percent={file.percent}
            status="active"
            className={progressCls}
            format={() => <span style={{ color: '#313E75' }}>{Math.round((file.percent || 0) * 100) / 100}%</span>}
          />
          <span className="loading-text">{uploading}</span>
        </div>
      ) : null}
      {file.status === STATUS_SUCCESS && (
        <>
          {isImageFile(file) || isOnlyAcceptImg(accept) ? (
            <>
              <Preview file={file} size="100%" />{' '}
              <Actions file={file} useUpload onRemove={onRemove} placement="rightTop" />
            </>
          ) : (
            <>
              <PreviewForNotImage onRemove={onRemove} onReSelect={onReSelect} file={file} />
              <Actions file={file} onRemove={onRemove} showModal={false} />
            </>
          )}
        </>
      )}
      {file.status === STATUS_ERROR && (
        <>
          {isOnlyAcceptImg(accept) ? (
            <div className={placeholderCls}>
              <PictureSVG style={{ width: currentWidth, height: currentHeight }} />
              <div>{picPending}</div>
            </div>
          ) : (
            <>
              <PreviewForNotImage onReSelect={onReSelect} file={file} onRemove={onRemove} />
              <Actions file={file} onRemove={onRemove} showModal={false} />
            </>
          )}
        </>
      )}
      {file.status === STATUS_NOT_YET &&
        (disabled ? (
          <div className={placeholderCls}>
            {isOnlyAcceptImg(accept) ? (
              <>
                <DisabledPictureSVG style={{ width: currentWidth, height: currentHeight }} />
                <div>{picPending}</div>
              </>
            ) : (
              <>
                <DisabledFolderSVG style={{ width: currentWidth, height: currentHeight }} />
                <div>{filePending}</div>
              </>
            )}
          </div>
        ) : (
          <div className={placeholderCls}>
            {isOnlyAcceptImg(accept) ? (
              <>
                <PictureSVG style={{ width: currentWidth, height: currentHeight }} />
                <div>{picPending}</div>
              </>
            ) : (
              <>
                <FolderSVG style={{ width: currentWidth, height: currentHeight }} />
                <div>{filePending}</div>
              </>
            )}
          </div>
        ))}
    </div>
  );

  // 批量上传渲染
  const renderMultipleUpload = () => {
    const currentProgress = (finishCount / fileListLength) * 100;
    const multiplePercent = fileListLength > 1 ? currentProgress : file.percent;
    return (
      <div className={cls} onDrop={handleDrag} onDragOver={handleDrag} onDragLeave={handleDrag} style={dragStyle}>
        {finishCount < fileListLength ? (
          <div className={`${prefixCls}__drag-container`}>
            <Progress
              percent={multiplePercent}
              status="active"
              className={progressCls}
              format={() => <span style={{ color: '#313E75' }}>{Math.round((multiplePercent || 0) * 100) / 100}%</span>}
            />
            <span className="loading-text">{uploading}</span>
          </div>
        ) : null}
        {fileListLength !== 0 &&
          finishCount === fileListLength &&
          (disabled ? (
            <div className={placeholderCls}>{renderDisabledPlaceholder()}</div>
          ) : (
            <div className={placeholderCls}>{renderPlaceholder()}</div>
          ))}
        {fileListLength === 0 && file.status === STATUS_NOT_YET && (
          <div className={placeholderCls}>
            {isOnlyAcceptImg(accept) ? (
              <PictureSVG style={{ width: currentWidth, height: currentHeight }} />
            ) : (
              <FolderSVG style={{ width: currentWidth, height: currentHeight }} />
            )}
            <div>{filePending}</div>
          </div>
        )}
      </div>
    );
  };
  const renderUpload = () => (directory || multiple ? renderMultipleUpload() : renderSingleUpload());
  return <>{renderUpload()}</>;
}