Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/crazy-roses-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"jsrepo": minor
---

feat: Add `includeFiles` to config to allow for serving any file type from a registry

6 changes: 6 additions & 0 deletions .changeset/rich-memes-bet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"jsrepo": patch
---

fix: Remove console.log in `build` command

7 changes: 7 additions & 0 deletions schemas/registry-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@
"type": "string"
}
},
"includeFiles": {
"description": "Additional files to include in the manifest. (Supports glob patterns)",
"type": "array",
"items": {
"type": "string"
}
},
"excludeBlocks": {
"description": "The names of the blocks that should not be included in the manifest.",
"type": "array",
Expand Down
7 changes: 7 additions & 0 deletions src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const schema = v.object({
outputDir: v.optional(v.string()),
includeBlocks: v.optional(v.array(v.string())),
includeCategories: v.optional(v.array(v.string())),
includeFiles: v.optional(v.array(v.string())),
excludeBlocks: v.optional(v.array(v.string())),
excludeCategories: v.optional(v.array(v.string())),
excludeDeps: v.optional(v.array(v.string())),
Expand Down Expand Up @@ -48,6 +49,10 @@ const build = new Command('build')
'--include-categories [categoryNames...]',
'Include only the categories with these names.'
)
.option(
'--include-files [filePatterns...]',
'Additional files to include in the manifest. (Supports glob patterns)'
)
.option('--exclude-blocks [blockNames...]', 'Do not include the blocks with these names.')
.option(
'--exclude-categories [categoryNames...]',
Expand Down Expand Up @@ -103,6 +108,7 @@ async function _build(options: Options) {
excludeDeps: options.excludeDeps ?? [],
includeBlocks: options.includeBlocks ?? [],
includeCategories: options.includeCategories ?? [],
includeFiles: options.includeFiles ?? [],
excludeBlocks: options.excludeBlocks ?? [],
excludeCategories: options.excludeCategories ?? [],
allowSubdirectories: options.allowSubdirectories,
Expand All @@ -124,6 +130,7 @@ async function _build(options: Options) {
if (options.listCategories) mergedVal.listCategories = options.listCategories;
if (options.includeBlocks) mergedVal.includeBlocks = options.includeBlocks;
if (options.includeCategories) mergedVal.includeCategories = options.includeCategories;
if (options.includeFiles) mergedVal.includeFiles = options.includeFiles;
if (options.excludeBlocks) mergedVal.excludeBlocks = options.excludeBlocks;
if (options.excludeCategories) mergedVal.excludeCategories = options.excludeCategories;
if (options.excludeDeps) mergedVal.excludeDeps = options.excludeDeps;
Expand Down
1 change: 1 addition & 0 deletions src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,7 @@ const _initRegistry = async (options: Options) => {
excludeDeps: [],
includeBlocks: [],
includeCategories: [],
includeFiles: [],
excludeBlocks: [],
excludeCategories: [],
preview: false,
Expand Down
3 changes: 3 additions & 0 deletions src/commands/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const schema = v.object({
dirs: v.optional(v.array(v.string())),
includeBlocks: v.optional(v.array(v.string())),
includeCategories: v.optional(v.array(v.string())),
includeFiles: v.optional(v.array(v.string())),
excludeBlocks: v.optional(v.array(v.string())),
excludeCategories: v.optional(v.array(v.string())),
excludeDeps: v.optional(v.array(v.string())),
Expand Down Expand Up @@ -109,6 +110,7 @@ async function _publish(options: Options) {
excludeDeps: options.excludeDeps ?? [],
includeBlocks: options.includeBlocks ?? [],
includeCategories: options.includeCategories ?? [],
includeFiles: options.includeFiles ?? [],
excludeBlocks: options.excludeBlocks ?? [],
excludeCategories: options.excludeCategories ?? [],
allowSubdirectories: options.allowSubdirectories,
Expand All @@ -131,6 +133,7 @@ async function _publish(options: Options) {
if (options.listCategories) mergedVal.listCategories = options.listCategories;
if (options.includeBlocks) mergedVal.includeBlocks = options.includeBlocks;
if (options.includeCategories) mergedVal.includeCategories = options.includeCategories;
if (options.includeFiles) mergedVal.includeFiles = options.includeFiles;
if (options.excludeBlocks) mergedVal.excludeBlocks = options.excludeBlocks;
if (options.excludeCategories) mergedVal.excludeCategories = options.excludeCategories;
if (options.excludeDeps) mergedVal.excludeDeps = options.excludeDeps;
Expand Down
19 changes: 19 additions & 0 deletions src/utils/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import fs from 'node:fs';
import color from 'chalk';
import { program } from 'commander';
import type { Ignore } from 'ignore';
import baseIgnore from 'ignore';
import path from 'pathe';
import * as v from 'valibot';
import { type Block, type Category, categorySchema, type Manifest } from '../../types';
Expand Down Expand Up @@ -187,12 +188,15 @@ export function buildBlocksDirectory(

const blockFiles: string[] = [];

const shouldIncludeFile = createShouldIncludeFile(config);

// if the user has enabled allow subdirectories we recursively check each directory and resolve any dependencies
const walkFiles = (base: string, files: string[]) => {
for (const f of files) {
const filePath = path.join(base, f);
// relative to the block root
const relativeFilePath = filePath.slice(blockDir.length + 1);
const relativeToRootDirectory = filePath.replace(cwd, '').replace('/', '');

if (isTestFile(f)) {
hasTests = true;
Expand All @@ -213,6 +217,11 @@ export function buildBlocksDirectory(
continue;
}

if (shouldIncludeFile(relativeToRootDirectory)) {
blockFiles.push(relativeFilePath);
continue;
}

if (fs.statSync(filePath).isDirectory()) {
if (!config.allowSubdirectories) {
console.warn(
Expand Down Expand Up @@ -411,6 +420,16 @@ export function shouldIncludeCategory(name: string, config: RegistryConfig) {
return true;
}

export function createShouldIncludeFile(config: RegistryConfig) {
if (config.includeFiles.length === 0) return () => false;

// Dispite it's name, the ignore package can also be used to include files.
// It's just a pattern matching library based on the .gitignore syntax.
const ignore = baseIgnore().add(config.includeFiles.map((p) => p.replace(/^(\.\/|\/)/, '')));

return (filePathRelativeToRoot: string) => ignore.ignores(filePathRelativeToRoot);
}

/** Takes the given file and returns the block name */
function transformBlockName(file: string) {
return path.parse(path.basename(file)).name;
Expand Down
1 change: 1 addition & 0 deletions src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const registryConfigSchema = v.object({
outputDir: v.optional(v.string()),
includeBlocks: v.optional(v.array(v.string()), []),
includeCategories: v.optional(v.array(v.string()), []),
includeFiles: v.optional(v.array(v.string()), []),
excludeBlocks: v.optional(v.array(v.string()), []),
excludeCategories: v.optional(v.array(v.string()), []),
doNotListBlocks: v.optional(v.array(v.string()), []),
Expand Down
1 change: 0 additions & 1 deletion src/utils/language-support/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { formatError, type Lang, resolveImports } from '.';
* @returns
*/
export function getJavascriptImports(fileName: string, code: string): string[] {
console.log('oxc', oxc);
const result = oxc.parseSync(fileName, code);

const modules: string[] = [];
Expand Down
108 changes: 108 additions & 0 deletions tests/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { afterAll, assert, beforeAll, describe, expect, it } from 'vitest';
import { cli } from '../src/cli';
import type { Manifest } from '../src/types';
import {
createShouldIncludeFile,
shouldIncludeBlock,
shouldIncludeCategory,
shouldListBlock,
Expand Down Expand Up @@ -65,6 +66,7 @@ describe('build', () => {
dirs: ['./src', './'],
includeBlocks: [],
includeCategories: [],
includeFiles: ['src/utils/block-with-asset/asset.txt'],
excludeBlocks: [],
excludeCategories: ['src'],
doNotListBlocks: ['noop'],
Expand Down Expand Up @@ -206,6 +208,19 @@ export const highlighter = createHighlighterCore({
</script>`
);

fs.mkdirSync('./src/utils/block-with-asset', { recursive: true });

fs.writeFileSync(
'./src/utils/block-with-asset/index.ts',
`import { fs } from 'node:fs';
const result = fs.readFileSync(new URL('./asset.txt', import.meta.url), 'utf-8');
console.log(result);
`
);

fs.writeFileSync('./src/utils/block-with-asset/asset.txt', 'This is an asset file.');

// build

await cli.parseAsync([
Expand Down Expand Up @@ -321,6 +336,20 @@ export const highlighter = createHighlighterCore({
'./log': '{{utils/log}}',
},
},
{
_imports_: {},
category: 'utils',
dependencies: [],
devDependencies: [],
directory: 'src/utils/block-with-asset',
docs: false,
files: ['asset.txt', 'index.ts'],
list: true,
localDependencies: [],
name: 'block-with-asset',
subdirectory: true,
tests: false,
},
{
name: 'form1',
category: 'utils',
Expand Down Expand Up @@ -395,6 +424,7 @@ const defaultConfig = {
excludeDeps: [],
includeBlocks: [],
includeCategories: [],
includeFiles: [],
excludeBlocks: [],
excludeCategories: [],
};
Expand Down Expand Up @@ -518,3 +548,81 @@ describe('shouldIncludeCategory', () => {
).toBe(false);
});
});

describe('shouldIncludeFile', () => {
it('does not list if unspecified', () => {
expect(
createShouldIncludeFile({ ...defaultConfig, includeDocs: false })(
'utils/math/asset.txt'
)
).toBe(false);
});

it('can include a file when referenced directly', () => {
expect(
createShouldIncludeFile({
...defaultConfig,
includeFiles: ['/utils/math/asset.txt'],
includeDocs: false,
})('utils/math/asset.txt')
).toBe(true);
});

it('is lenient to leading slashes', () => {
expect(
createShouldIncludeFile({
...defaultConfig,
includeFiles: ['/utils/math/asset.txt'],
includeDocs: false,
})('utils/math/asset.txt')
).toBe(true);
expect(
createShouldIncludeFile({
...defaultConfig,
includeFiles: ['./utils/math/asset.txt'],
includeDocs: false,
})('utils/math/asset.txt')
).toBe(true);
});

it('it can include all files of a certain extension', () => {
expect(
createShouldIncludeFile({
...defaultConfig,
includeFiles: ['**/*.txt'],
includeDocs: false,
})('utils/math/asset.txt')
).toBe(true);
expect(
createShouldIncludeFile({
...defaultConfig,
includeFiles: ['**/*.png'],
includeDocs: false,
})('utils/math/asset.png')
).toBe(true);
expect(
createShouldIncludeFile({
...defaultConfig,
includeFiles: ['**/*.png'],
includeDocs: false,
})('utils/math/asset.jpg')
).toBe(false);
});

it('it can include all files in a certain directory', () => {
expect(
createShouldIncludeFile({
...defaultConfig,
includeFiles: ['utils/math/files-to-include/**'],
includeDocs: false,
})('utils/math/files-to-include/asset.txt')
).toBe(true);
expect(
createShouldIncludeFile({
...defaultConfig,
includeFiles: ['utils/math/files-to-include/**'],
includeDocs: false,
})('utils/math/files-to-include/image.png')
).toBe(true);
});
});
Loading