fs-extra#ensureFile TypeScript Examples

The following examples show how to use fs-extra#ensureFile. 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: compareImages.ts    From cucumber-playwright with MIT License 6 votes vote down vote up
export async function compareToBaseImage(
  customWorld: ICustomWorld,
  name: string,
  screenshot: Buffer,
  threshold?: { threshold: number },
) {
  let baseImage;
  const baseImagePath = getImagePath(customWorld, name);
  const baseImgExist = await pathExists(baseImagePath);
  if (baseImgExist) {
    baseImage = PNG.sync.read(fs.readFileSync(baseImagePath));
  } else {
    await ensureFile(baseImagePath);
    writeFileSync(baseImagePath, screenshot);
    customWorld.log(
      `The base Image doesn't exist, a screenshot was taken to ${baseImagePath} so it can be used for next run`,
    );
    return;
  }
  const img1 = PNG.sync.read(screenshot);
  const difference = getDifference(img1, baseImage, threshold);
  if (difference) {
    await customWorld.attach(difference, 'image/png;base64');
    throw new Error(`Screenshot does not match : ${baseImagePath}`);
  }
}
Example #2
Source File: index.ts    From pancake-bot with MIT License 6 votes vote down vote up
export default async function moduleInit(mod: BotModule) {
    const sudoersDBPath = path.join(mod.dataDir, 'sudoers.json');
    const adminDBPath = path.join(mod.dataDir, 'admins.json');
    await ensureFile(adminDBPath);
    await ensureFile(sudoersDBPath);

    mod.logger.info('admin db 불러오는 중...');
    const adminDB = await low(new FileAsync(adminDBPath, { defaultValue: {} }));
    mod.logger.info('admin db 로드 완료');

    mod.logger.info('sudoers 불러오는 중...');
    const sudoersDB = await low(new FileAsync(sudoersDBPath, { defaultValue: {} }));
    mod.logger.info('sudoers 로드 완료');

    new ExecuteManager(mod, 'sudoers', 'sudoer', 'sudo', OpenChannelUserPerm.OWNER, sudoersDB);
    new ExecuteManager(mod, 'admins', 'admin', 'mod', OpenChannelUserPerm.MANAGER, adminDB);
}
Example #3
Source File: npm.ts    From DefinitelyTyped-tools with MIT License 5 votes vote down vote up
export async function withNpmCache<T>(
  uncachedClient: UncachedNpmInfoClient,
  cb: (client: CachedNpmInfoClient) => Promise<T>,
  cacheDir = defaultCacheDir
): Promise<T> {
  const log = loggerWithErrors()[0];
  const cacheFile = joinPaths(cacheDir, cacheFileBasename);
  let unroll: Map<string, NpmInfo>;
  log.info(`Checking for cache file at ${cacheFile}...`);
  const cacheFileExists = await pathExists(cacheFile);
  if (cacheFileExists) {
    log.info("Reading cache file...");
    const cachedJson = (await readJson(cacheFile)) as Record<string, NpmInfoRaw>;
    log.info(`Cache file ${cacheFile} exists, copying to map...`);
    unroll = recordToMap(cachedJson, npmInfoFromJson);
  } else {
    log.info("Cache file doesn't exist, using empty map.");
    unroll = new Map();
  }

  const res = await cb({ getNpmInfoFromCache, fetchAndCacheNpmInfo });
  log.info("Writing npm cache.");
  await ensureFile(cacheFile);
  await writeJson(cacheFile, mapToRecord(unroll, jsonFromNpmInfo));
  return res;

  /** May return old info -- caller should check that this looks up-to-date. */
  function getNpmInfoFromCache(escapedPackageName: string): NpmInfo | undefined {
    return unroll.get(escapedPackageName);
  }

  /** Call this when the result of getNpmInfoFromCache looks potentially out-of-date. */
  async function fetchAndCacheNpmInfo(escapedPackageName: string): Promise<NpmInfo | undefined> {
    const info = await uncachedClient.fetchNpmInfo(escapedPackageName);
    if (info) {
      unroll.set(escapedPackageName, info);
    }
    return info;
  }
}
Example #4
Source File: index.ts    From cli with MIT License 5 votes vote down vote up
async package() {
    this.core.cli.log('Package artifact...');
    // 跳过打包
    if (this.options.skipZip) {
      this.core.cli.log(' - Zip artifact skip');
      if (this.core.service?.experimentalFeatures?.removeUselessFiles) {
        this.core.cli.log(' - Experimental Feature RemoveUselessFiles');
        await removeUselessFiles(this.midwayBuildPath);
      }
      return;
    }
    // 构建打包
    const packageObj: any = this.core.service.package || {};

    let file = join(this.servicePath, this.zipCodeDefaultName);

    if (packageObj.artifact) {
      if (isAbsolute(packageObj.artifact)) {
        file = packageObj.artifact;
      } else {
        file = join(this.servicePath, packageObj.artifact);
      }
    }

    this.setStore('artifactFile', file, true);
    this.core.cli.log(` - Artifact file ${relative(this.servicePath, file)}`);

    // 保证文件存在,然后删了文件,只留目录
    await ensureFile(file);
    await remove(file);

    await this.makeZip(this.midwayBuildPath, file);
    const stat = statSync(file);
    this.setStore('zipSize', stat.size, true);
    this.core.cli.log(
      ` - Zip size ${Number(stat.size / (1024 * 1024)).toFixed(2)}MB`
    );
    if (this.options.package) {
      const to = resolve(this.servicePath, this.options.package);
      await move(file, to);
    }
  }
Example #5
Source File: postInstall.ts    From cli with MIT License 5 votes vote down vote up
postInstallModule = async (
  moduleList: { name: string; version: string }[]
) => {
  const info = await postInstall();
  if (!info) {
    return;
  }
  const { cwd, pkg } = info;
  const { registry, npm } = findNpm();
  const modules = [];
  for (const { name, version } of moduleList) {
    if (pkg?.dependencies?.[name] || pkg?.devDependencies?.[name]) {
      continue;
    }
    console.log('[midway] auto install', name);
    modules.push(name + '@' + version);
  }

  if (!modules.length) {
    return;
  }
  const installingLock = join(
    cwd,
    `node_modules/.midwayjs-cli/postInstallLock/${modules
      .join('_')
      .replace(/\//g, '_')}.lock`
  );
  if (existsSync(installingLock)) {
    return;
  }
  await ensureFile(installingLock);
  await writeFile(installingLock, JSON.stringify({ cwd, npm, registry }));
  await installNpm({
    baseDir: cwd,
    mode: ['save-dev'],
    register: ['yarn'].includes(npm) ? 'npm' : npm,
    registerPath: registry,
    moduleName: modules.join(' '),
    slience: true,
  });
  console.log('[midway] auto install complete');
  return;
}
Example #6
Source File: index.ts    From pancake-bot with MIT License 5 votes vote down vote up
export default async function moduleInit(mod: BotModule) {
    mod.on('chat', (ctx) => logChat(ctx, mod.logger));

    mod.commandHandler.open.addListener(
        new ChatCmdListener(
            ['hide'],
            { usage: 'hide [챗 logId]', description: '선택된 채팅 또는 인자로 제공된 id 채팅을 가립니다', executeLevel: OpenChannelPerms.MANAGERS },
            (info, ctx) => hideChat(info, ctx)
        )
    );
    
    mod.commandHandler.any.addListener(
        new ChatCmdListener(
            ['chatlog', 'chatlogs'],
            { usage: 'chatlog [채팅 수]', description: '선택된 채팅 이전의 채팅을 최대 300개까지 가져옵니다. 기본: 50', executeLevel: OpenChannelPerms.MANAGERS },
            async (info, ctx) => {
                let logId: Long | undefined;
                if (ctx.data.originalType === KnownChatType.REPLY) {
                    const reply = ctx.data.attachment<ReplyAttachment>();
                    if (reply['src_logId']) {
                        logId = reply['src_logId'];
                    } else {
                        await ctx.channel.sendChat('채팅 정보를 가져오는데 실패했습니다');
                        return;
                    }
                }

                if (!logId) {
                    const lastChat = await ctx.channel.chatListStore.last();

                    logId = lastChat?.logId;
                }

                if (!logId) {
                    await ctx.channel.sendChat('답장 기능을 통해 채팅을 선택해주세요');
                    return;
                }

                let count;

                if (info.args.length > 0) {
                    count = Number.parseInt(info.args);
                }

                if (!count || isNaN(count)) count = 50;

                const iter = ctx.channel.chatListStore.before(logId, count);

                let text = `${ctx.channel.getDisplayName()} 챗 기록${LONG_CHAT_SPLITTER}\n\n`;
                let i = 0;
                for await (const chat of iter) {
                    const data = new TalkChatData(chat);
                    const info = data.getSenderInfo(ctx.channel);
                    const name = info ? info.nickname : '(알수없음)';

                    text += `(${i}) [${data.sendAt.toLocaleString()}] (logId: ${chat.logId}) ${name} (senderId: ${chat.sender.userId}) (type: ${data.originalType}) ${data.isDeleted() ? '(deleted)' : ''}: ${chat.text}\n`;
                    if (chat.attachment && Object.keys(chat.attachment).length > 0) {
                        text += `attachment: ${util.JsonUtil.stringifyLoseless(chat.attachment)}\n`;
                    }
                    i++;
                }

                await ctx.channel.sendMedia(KnownChatType.TEXT, {
                    data: Buffer.from(text),
                    name: 'log.txt',
                    ext: 'txt'
                });
            }
        )
    );

    const filterDBPath = path.join(mod.dataDir, 'filters.json');
    await ensureFile(filterDBPath);

    mod.logger.info('챗 필터를 불러오는 중...');
    const filterDB = await low(new FileAsync(filterDBPath, { defaultValue: {} }));
    mod.logger.info('챗 필터 로드 완료');

    const manager = new ChatFilterManager(mod, filterDB);
}
Example #7
Source File: index.ts    From cli with MIT License 4 votes vote down vote up
// 合并高密度部署
  async checkAggregation() {
    // 只在部署阶段生效
    const commands = this.core.processedInput.commands;
    if (
      !commands ||
      !commands.length ||
      (commands[0] !== 'deploy' && commands[0] !== 'package')
    ) {
      return;
    }
    if (!this.core.service.aggregation || !this.core.service.functions) {
      return;
    }

    // if (
    //   !this.core.service.custom ||
    //   !this.core.service.custom.customDomain ||
    //   !this.core.service.custom.customDomain.domainName
    // ) {
    //   console.warn(
    //     'If using aggregation deploy, it is best to configure custom domain'
    //   );
    // }

    this.core.cli.log('Aggregation Deploy');

    // use picomatch to match url
    const allAggregationPaths = [];
    let allFuncNames = Object.keys(this.core.service.functions);
    for (const aggregationName in this.core.service.aggregation) {
      const aggregationConfig = this.core.service.aggregation[aggregationName];
      const aggregationFuncName = this.getAggregationFunName(aggregationName);
      this.core.service.functions[aggregationFuncName] = aggregationConfig;
      this.core.service.functions[
        aggregationFuncName
      ].handler = `${aggregationFuncName}.handler`;
      this.core.service.functions[aggregationFuncName]._isAggregation = true;
      if (!this.core.service.functions[aggregationFuncName].events) {
        this.core.service.functions[aggregationFuncName].events = [];
      }
      // 忽略原始方法,不再单独进行部署
      const deployOrigin = aggregationConfig.deployOrigin;

      let handlers = [];
      const allAggredHttpTriggers = [];
      const allAggredEventTriggers = [];
      if (aggregationConfig.functions || aggregationConfig.functionsPattern) {
        const matchedFuncName = [];
        const notMatchedFuncName = [];
        const functions = this.core.service.functions;
        for (const functionName of allFuncNames) {
          const func = functions[functionName];
          const isHttpFunction = func.events?.find(event => {
            return Object.keys(event)[0] === 'http';
          });
          // http 函数并且开启了 eventTrigger,需要忽略
          // 非 http 函数,并且没有开启  eventTrigger,需要忽略
          let isMatch = false;
          if (
            (isHttpFunction && aggregationConfig.eventTrigger) ||
            (!isHttpFunction && !aggregationConfig.eventTrigger)
          ) {
            isMatch = false;
          } else if (aggregationConfig.functions) {
            isMatch = aggregationConfig.functions.indexOf(functionName) !== -1;
          } else if (aggregationConfig.functionsPattern) {
            isMatch = micromatch.all(
              functionName,
              aggregationConfig.functionsPattern
            );
          }
          if (isMatch) {
            matchedFuncName.push(functionName);
          } else {
            notMatchedFuncName.push(functionName);
          }
        }
        allFuncNames = notMatchedFuncName;
        matchedFuncName.forEach((functionName: string) => {
          const functions = this.core.service.functions;
          const func = functions[functionName];
          if (!func || !func.events) {
            return;
          }

          for (const event of func.events) {
            const eventType = Object.keys(event)[0];
            const handlerInfo: any = {
              ...func,
              functionName,
              eventType,
            };
            if (eventType === 'http') {
              const httpInfo = {
                path: event.http.path,
                method: event.http.method,
              };
              allAggredHttpTriggers.push(httpInfo);
              Object.assign(handlerInfo, httpInfo);
            } else if (aggregationConfig.eventTrigger) {
              // 事件触发器支持
              const existsEventTrigger = handlers.find(
                handlerInfo => handlerInfo.eventType === eventType
              );
              if (!existsEventTrigger) {
                allAggredEventTriggers.push(event);
              }
            } else {
              continue;
            }
            if (!deployOrigin) {
              // 不把原有的函数进行部署
              this.core.cli.log(
                ` - using function '${aggregationName}' to deploy '${functionName}'`
              );
              delete this.core.service.functions[functionName];
            }

            handlers.push(handlerInfo);
          }
        });
      }
      handlers = handlers.filter((func: any) => !!func);

      this.core.service.functions[aggregationFuncName]._handlers = handlers;
      this.core.service.functions[aggregationFuncName]._allAggred =
        allAggredHttpTriggers;
      this.core.service.functions[aggregationFuncName].events =
        allAggredEventTriggers;

      if (allAggredHttpTriggers?.length) {
        const allPaths = allAggredHttpTriggers.map(aggre => aggre.path);
        let currentPath = commonPrefix(allPaths);
        currentPath =
          currentPath && currentPath !== '/' ? `${currentPath}/*` : '/*';

        this.core.cli.log(
          ` - using path '${currentPath}' to deploy '${allPaths.join("', '")}'`
        );
        // path parameter
        if (currentPath.includes(':')) {
          const newCurrentPath = currentPath.replace(/\/:.*$/, '/*');
          this.core.cli.log(
            ` - using path '${newCurrentPath}' to deploy '${currentPath}' (for path parameter)`
          );
          currentPath = newCurrentPath;
        }
        if (allAggregationPaths.indexOf(currentPath) !== -1) {
          console.error(
            `Cannot use the same prefix '${currentPath}' for aggregation deployment`
          );
          process.exit(1);
        }
        allAggregationPaths.push(currentPath);
        this.core.service.functions[aggregationFuncName].events.push({
          http: { method: 'any', path: currentPath },
        });
      }
    }

    const tmpSpecFile = resolve(tmpdir(), `aggre-${Date.now()}/f.yml`);
    await ensureFile(tmpSpecFile);

    this.core.config.specFile.path = tmpSpecFile;
    writeToSpec(this.servicePath, this.core.service, this.core.config.specFile);
  }