fs-extra#readdir TypeScript Examples

The following examples show how to use fs-extra#readdir. 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: dev.ts    From gdmod with MIT License 6 votes vote down vote up
async function buildMod() {
  const zip = new JSZip();

  // Copy resources
  await Promise.all(
    (
      await readdir("./resources")
    ).map(async (file) =>
      zip.file("resources/" + file, await readFile("./resources/" + file))
    )
  );

  // Read manifests
  const [gdmod, resources, bundle] = await Promise.all([
    await readFile("./data/GDMod.json"),
    await readFile("./data/resources.json"),
    await readFile("./dist/bundle.js"),
  ]);

  return new Promise(async (resolve, reject) =>
    zip
      .file("data/GDMod.json", gdmod)
      .file("data/resources.json", resources)
      .file("data/includes.json", `["bundle.js"]`)
      .file("code/bundle.js", bundle)
      .generateNodeStream()
      .pipe(createWriteStream("./dist/mod.zip"))
      .once("finish", resolve)
      .once("error", reject)
  );
}
Example #2
Source File: log.ts    From backstage with Apache License 2.0 6 votes vote down vote up
export async function recursiveReadDir(dir: string): Promise<string[]> {
  const subdirs = await readdir(dir);
  const files = await Promise.all(
    subdirs.map(async subdir => {
      const res = join(dir, subdir);
      return (await stat(res)).isDirectory() ? recursiveReadDir(res) : [res];
    }),
  );
  return files.reduce((a, f) => a.concat(f), []);
}
Example #3
Source File: BinCommand.ts    From joplin-blog with MIT License 6 votes vote down vote up
/**
   * 生成类型定义
   */
  async gen(options: { input?: string }) {
    if (!options.input) {
      return
    }
    const i18nFolderPath = path.resolve(options.input)
    const list = await readdir(i18nFolderPath)
    const i18nJsonPathList = list
      .filter((name) => name.endsWith('.json'))
      .map((name) => path.resolve(i18nFolderPath, name))
    const jsonList = await AsyncArray.map(i18nJsonPathList, (filePath) =>
      readJSON(filePath),
    )
    const translateHandler = new TranslateHandler()
    const configList = translateHandler.parse(jsonList)
    const dts = translateHandler.build(configList)
    await writeFile(path.resolve(i18nFolderPath, 'index.d.ts'), dts)
  }
Example #4
Source File: convert.test.ts    From joplin-utils with MIT License 6 votes vote down vote up
async function migrate2To3(dirs: string[]) {
  await AsyncArray.forEach(dirs, async (dir) => {
    await AsyncArray.map(await readdir(path.resolve(dir)), async (file) => {
      const jsonPath = path.resolve(dir, file as string)
      await writeJson(jsonPath, flatObject(await readJson(jsonPath)), {
        spaces: 2,
      })
    })
  })
  await new GeneratorCommandProgram().main({
    dirs,
    language: 'en',
    watch: false,
  })
}
Example #5
Source File: index.ts    From joplin-utils with MIT License 6 votes vote down vote up
joplin.plugins.register({
  onStart: async function () {
    await joplin.commands.register({
      name: 'hello',
      label: 'hello world',
      async execute(): Promise<any> {
        const list = await readdir(path.resolve(os.userInfo().homedir))
        alert('list: ' + list.join(', '))
      },
    })
  },
})
Example #6
Source File: image-compressor.ts    From image-optimizer with MIT License 5 votes vote down vote up
readdirAsync = util.promisify(readdir)
Example #7
Source File: index.ts    From DefinitelyTyped-tools with MIT License 5 votes vote down vote up
async function runTests(
  dirPath: string,
  onlyTestTsNext: boolean,
  expectOnly: boolean,
  tsLocal: string | undefined
): Promise<void> {
  const isOlderVersion = /^v(0\.)?\d+$/.test(basename(dirPath));

  const indexText = await readFile(joinPaths(dirPath, "index.d.ts"), "utf-8");
  // If this *is* on DefinitelyTyped, types-publisher will fail if it can't parse the header.
  const dt = indexText.includes("// Type definitions for");
  if (dt) {
    // Someone may have copied text from DefinitelyTyped to their type definition and included a header,
    // so assert that we're really on DefinitelyTyped.
    const dtRoot = findDTRoot(dirPath);
    const packageName = basename(dirPath);
    assertPathIsInDefinitelyTyped(dirPath, dtRoot);
    assertPathIsNotBanned(packageName);
    assertPackageIsNotDeprecated(packageName, await readFile(joinPaths(dtRoot, "notNeededPackages.json"), "utf-8"));
  }

  const typesVersions = await mapDefinedAsync(await readdir(dirPath), async (name) => {
    if (name === "tsconfig.json" || name === "tslint.json" || name === "tsutils") {
      return undefined;
    }
    const version = withoutPrefix(name, "ts");
    if (version === undefined || !(await stat(joinPaths(dirPath, name))).isDirectory()) {
      return undefined;
    }

    if (!TypeScriptVersion.isTypeScriptVersion(version)) {
      throw new Error(`There is an entry named ${name}, but ${version} is not a valid TypeScript version.`);
    }
    if (!TypeScriptVersion.isRedirectable(version)) {
      throw new Error(`At ${dirPath}/${name}: TypeScript version directories only available starting with ts3.1.`);
    }
    return version;
  });

  if (dt) {
    await checkPackageJson(dirPath, typesVersions);
  }

  const minVersion = maxVersion(
    getMinimumTypeScriptVersionFromComment(indexText),
    TypeScriptVersion.lowest
  ) as TypeScriptVersion;
  if (onlyTestTsNext || tsLocal) {
    const tsVersion = tsLocal ? "local" : TypeScriptVersion.latest;
    await testTypesVersion(dirPath, tsVersion, tsVersion, isOlderVersion, dt, expectOnly, tsLocal, /*isLatest*/ true);
  } else {
    // For example, typesVersions of [3.2, 3.5, 3.6] will have
    // associated ts3.2, ts3.5, ts3.6 directories, for
    // <=3.2, <=3.5, <=3.6 respectively; the root level is for 3.7 and above.
    // so this code needs to generate ranges [lowest-3.2, 3.3-3.5, 3.6-3.6, 3.7-latest]
    const lows = [TypeScriptVersion.lowest, ...typesVersions.map(next)];
    const his = [...typesVersions, TypeScriptVersion.latest];
    assert.strictEqual(lows.length, his.length);
    for (let i = 0; i < lows.length; i++) {
      const low = maxVersion(minVersion, lows[i]);
      const hi = his[i];
      assert(
        parseFloat(hi) >= parseFloat(low),
        `'// Minimum TypeScript Version: ${minVersion}' in header skips ts${hi} folder.`
      );
      const isLatest = hi === TypeScriptVersion.latest;
      const versionPath = isLatest ? dirPath : joinPaths(dirPath, `ts${hi}`);
      if (lows.length > 1) {
        console.log("testing from", low, "to", hi, "in", versionPath);
      }
      await testTypesVersion(versionPath, low, hi, isOlderVersion, dt, expectOnly, undefined, isLatest);
    }
  }
}
Example #8
Source File: Application.ts    From joplin-utils with MIT License 5 votes vote down vote up
async cache<
    T extends CommonNote & {
      resources: CommonResource[]
      tags: CommonTag[]
    },
  >(allNoteList: T[]) {
    const cache = await cacheCommanderProgram.read()
    const noteDiff = CacheUtil.diff({
      old: cache.note,
      new: allNoteList,
      id: (item) => item.id + '-' + item.updatedTime,
    })
    await AsyncArray.forEach(noteDiff.remove, async (item) => {
      await remove(path.resolve(this.handler.notePath, (this.handler.formatFileName ?? ((id) => id))(item.id) + '.md'))
    })
    const allResourceList = uniqueBy(
      allNoteList.flatMap((item) => item.resources),
      (resource) => resource.id,
    )
    const resourceDiff = CacheUtil.diff({
      old: cache.resource,
      new: allResourceList,
      id: (item) => item.id + '-' + item.user_updated_time,
    })
    const removeIdSet = new Set(resourceDiff.remove.map((item) => item.id))
    const removeResourceFileNameList = (await readdir(this.handler.resourcePath)).filter((fileName) =>
      removeIdSet.has(path.basename(fileName)),
    )
    await AsyncArray.forEach(removeResourceFileNameList, async (fileName) => {
      await remove(path.resolve(this.handler.resourcePath, fileName))
    })
    return {
      noteList: noteDiff.update,
      resourceList: resourceDiff.update,
      skipResourceCount: allResourceList.length - resourceDiff.update.length,
      async updateCache() {
        await cacheCommanderProgram.write({
          note: allNoteList,
          resource: allResourceList,
        })
      },
    }
  }
Example #9
Source File: ui5-model-spec.ts    From ui5-language-assistant with Apache License 2.0 4 votes vote down vote up
describe("the UI5 language assistant ui5 model", () => {
  // The default timeout is 2000ms and getSemanticModel can take ~3000-5000ms
  const GET_MODEL_TIMEOUT = 10000;
  const VERSION = "1.71.14";
  const NO_CACHE_FOLDER = undefined;

  function assertSemanticModel(ui5Model: UI5SemanticModel): void {
    expect(ui5Model.version).to.equal(VERSION);

    expect(Object.keys(ui5Model.classes).length).to.be.greaterThan(200);
    expect(Object.keys(ui5Model.namespaces).length).to.be.greaterThan(200);
    expect(Object.keys(ui5Model.interfaces).length).to.be.greaterThan(30);
    expect(Object.keys(ui5Model.functions).length).to.be.greaterThan(30);
    expect(Object.keys(ui5Model.enums).length).to.be.greaterThan(200);
    expect(Object.keys(ui5Model.typedefs).length).to.be.greaterThan(10);

    expect(Object.keys(ui5Model.classes)).to.include("sap.m.List");
    expect(Object.keys(ui5Model.namespaces)).to.include("sap.m");
    expect(Object.keys(ui5Model.interfaces)).to.include("sap.f.ICard");
    expect(Object.keys(ui5Model.functions)).to.include(
      "module:sap/base/assert"
    );
    expect(Object.keys(ui5Model.enums)).to.include("sap.m.ButtonType");
    expect(Object.keys(ui5Model.typedefs)).to.include("sap.ui.fl.Selector");

    // Dist layer
    expect(Object.keys(ui5Model.classes)).to.include("sap.ui.vk.Camera");
    expect(Object.keys(ui5Model.namespaces)).to.include("sap.apf.base");
    expect(Object.keys(ui5Model.enums)).to.include(
      "sap.ca.ui.charts.ChartSelectionMode"
    );
  }

  it("will get UI5 semantic model", async () => {
    const ui5Model = await getSemanticModel(NO_CACHE_FOLDER);
    assertSemanticModel(ui5Model);
  }).timeout(GET_MODEL_TIMEOUT);

  it("doesn't fail if a file cannot be fetched", async () => {
    const ui5Model = await getSemanticModelWithFetcher(async (url: string) => {
      return {
        ok: false,
        json: (): never => {
          throw new Error(`Cannot read from ${url}`);
        },
      };
    }, NO_CACHE_FOLDER);
    expect(ui5Model).to.exist;
  });

  describe("with cache", () => {
    describe("cache in temp dir", () => {
      let cachePath: string;
      beforeEach(async () => {
        ({ path: cachePath } = await tempDir());
      });

      afterEach(async () => {
        // The temp folder will contain files at the end so we remove it
        // with rimraf instead of calling cleanup()
        rimrafSync(cachePath);
      });

      it("caches the model the first time getSemanticModel is called", async () => {
        const ui5Model = await getSemanticModel(cachePath);
        assertSemanticModel(ui5Model);

        // Check the files were created in the folder
        const files = await readdir(cachePath);
        expect(files).to.not.be.empty;

        // Call getSemanticModel again with the same path and check it doesn't try to read from the URL
        let fetcherCalled = false;
        const ui5ModelFromCache = await getSemanticModelWithFetcher(
          (url: string): never => {
            fetcherCalled = true;
            throw new Error(
              `The files should be taken from the cache, got call for ${url}`
            );
          },
          cachePath
        );
        expect(fetcherCalled).to.be.false;
        // Make sure it's not the model itself that is cached
        expect(ui5ModelFromCache).to.not.equal(ui5Model);
        // Check we got the same result (we can't use deep equal so the check is shallow)
        forEach(ui5Model, (value, key) => {
          if (isPlainObject(value)) {
            expect(
              Object.keys(
                ui5ModelFromCache[key as keyof UI5SemanticModel] as Record<
                  string,
                  unknown
                >
              )
            ).to.deep.equalInAnyOrder(
              Object.keys(value as Record<string, unknown>)
            );
          }
        });
        assertSemanticModel(ui5ModelFromCache);
      }).timeout(GET_MODEL_TIMEOUT);

      it("doesn't fail when file cannot be written to the cache", async () => {
        // Create a folder with the file name so the file will not be written
        const cacheFilePath = getCacheFilePath(
          getCacheFolder(cachePath, VERSION),
          "sap.m"
        );
        expectExists(cacheFilePath, "cacheFilePath");
        await mkdirs(cacheFilePath);

        const ui5Model = await getSemanticModel(cachePath);
        expect(ui5Model).to.exist;
        // Check we still got the sap.m library data
        expect(Object.keys(ui5Model.namespaces)).to.contain("sap.m");
        expect(ui5Model.namespaces["sap.m"].library).to.equal("sap.m");
      }).timeout(GET_MODEL_TIMEOUT);

      it("doesn't fail when file cannot be read from the cache", async () => {
        // Create a file with non-json content so the file will not be deserialized
        const cacheFolder = getCacheFolder(cachePath, VERSION);
        await mkdirs(cacheFolder);
        const cacheFilePath = getCacheFilePath(cacheFolder, "sap.m");
        expectExists(cacheFilePath, "cacheFilePath");
        await writeFile(cacheFilePath, "not json");

        const ui5Model = await getSemanticModel(cachePath);
        expect(ui5Model).to.exist;
        // Check we still got the sap.m library data
        expect(Object.keys(ui5Model.namespaces)).to.contain("sap.m");
        expect(ui5Model.namespaces["sap.m"].library).to.equal("sap.m");
      }).timeout(GET_MODEL_TIMEOUT);
    });

    describe("cache path is a file", async () => {
      let cachePath: string;
      let cleanup: () => Promise<void>;
      beforeEach(async () => {
        ({ path: cachePath, cleanup } = await tempFile());
      });

      afterEach(async () => {
        await cleanup();
      });

      it("does not cache the model", async () => {
        const ui5Model = await getSemanticModel(cachePath);
        assertSemanticModel(ui5Model);

        // Call getSemanticModel again with the same path and check it doesn't try to read from the URL
        let fetcherCalled = false;
        await getSemanticModelWithFetcher(async (): Promise<FetchResponse> => {
          fetcherCalled = true;
          return {
            ok: true,
            json: async (): Promise<unknown> => {
              return {};
            },
          };
        }, cachePath);
        expect(fetcherCalled).to.be.true;
      }).timeout(GET_MODEL_TIMEOUT);
    });
  });
});