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
5 changes: 5 additions & 0 deletions .changeset/shaggy-clouds-stick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@oviirup/sprite': patch
---

📦 using `tinyglobby` instead of `fast-glob`
1 change: 0 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ name: CI

on:
push:
branches: [main]
pull_request:

permissions:
Expand Down
5 changes: 5 additions & 0 deletions .husky/post-checkout
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

# After checking out a branch (or after cloning the repo),
# ensure all Git submodules are initialized and updated.
git submodule update --init --recursive
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

# Run lint-staged to automatically lint files before committing.
pnpm lint-staged
10 changes: 8 additions & 2 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
{
"$schema": "https://json.schemastore.org/prettierrc.json",
"arrowParens": "always",
"plugins": ["prettier-plugin-imports", "prettier-plugin-jsdoc", "prettier-plugin-pkg"],
"printWidth": 120,
"endOfLine": "lf",
"plugins": [
"prettier-plugin-pkg",
"prettier-plugin-imports",
"prettier-plugin-jsdoc"
],
"printWidth": 80,
"quoteProps": "consistent",
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all"
}
15 changes: 1 addition & 14 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,5 @@
"explorer.sortOrder": "type",
"typescript.tsdk": "node_modules/typescript/lib",
// eslint for monorepo
"eslint.workingDirectories": [{ "mode": "auto" }],
// file nesting
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.expand": false,
"explorer.fileNesting.patterns": {
"package.json": ".nvmrc, .npm*, bun.lock*, pnpm*",
"*.js": "",
"*.ts": "$(capture).*.ts, $(capture).*.js"
},
"cSpell.language": "en-gb",
// prettier-ignore
"cSpell.words": [
"vite","webext","graygalaxy","tsup","newtab","picocolors"
]
"eslint.workingDirectories": [{ "mode": "auto" }]
}
266 changes: 233 additions & 33 deletions bun.lock

Large diffs are not rendered by default.

37 changes: 25 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"sprite": "./dist/bin.js"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"module": "./dist/index.mjs",
"exports": {
"./schema.json": "./schema.json",
Expand Down Expand Up @@ -64,39 +65,51 @@
"build:schema": "bun scripts/schema",
"clean": "npx rimraf node_modules dist",
"dev": "bunchee -w",
"format": "prettier -w -u --cache .",
"format:check": "prettier --check -u .",
"lint": "eslint src --ext .ts",
"format": "prettier -wu . --cache",
"format:check": "prettier -cu .",
"lint": "eslint src/**/*.ts",
"prepare": "husky",
"types:check": "tsc --noEmit"
},
"dependencies": {
"chokidar": "~4.0.3",
"commander": "~13.1.0",
"fast-glob": "~3.3.3",
"node-html-parser": "~7.0.1",
"picocolors": "~1.1.1",
"tinyglobby": "~0.2.13",
"yaml": "~2.7.1",
"zod": "~3.24.3"
"zod": "~3.24.4"
},
"devDependencies": {
"@changesets/changelog-github": "~0.5.1",
"@changesets/cli": "~2.29.2",
"@eslint/js": "~9.25.1",
"@types/bun": "~1.2.10",
"@changesets/cli": "~2.29.4",
"@eslint/js": "~9.26.0",
"@types/bun": "~1.2.13",
"bunchee": "~6.5.1",
"eslint": "~9.25.1",
"eslint-config-prettier": "~10.1.2",
"eslint": "~9.26.0",
"eslint-config-prettier": "~10.1.5",
"eslint-plugin-only-warn": "~1.1.0",
"husky": "~9.1.7",
"lint-staged": "~16.0.0",
"prettier": "~3.5.3",
"prettier-plugin-imports": "~4.3.3",
"prettier-plugin-jsdoc": "~1.3.2",
"prettier-plugin-pkg": "~0.19.0",
"prettier-plugin-pkg": "~0.19.1",
"typescript": "~5.8.3",
"typescript-eslint": "~8.31.0",
"typescript-eslint": "~8.32.1",
"zod-to-json-schema": "~3.24.5"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public"
},
"lint-staged": {
"*.{js,mjs,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{css,json,md,mdx,yaml,gql,xml,svg}": [
"prettier --write"
]
}
}
8 changes: 6 additions & 2 deletions src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ export function initialize({ root, useYAML = false }: InitOptions) {
}

const blankRecord: SpriteRecord & { $schema?: string } = {
$schema: useYAML ? undefined : `https://unpkg.com/@oviirup/sprite@${PKG_VERSION}/schema.json`,
$schema: useYAML
? undefined
: `https://unpkg.com/@oviirup/sprite@${PKG_VERSION}/schema.json`,
name: 'icons',
output: 'public/icons.svg',
icons: {
Expand All @@ -55,7 +57,9 @@ export function initialize({ root, useYAML = false }: InitOptions) {
};

try {
const content = useYAML ? yaml.stringify(blankRecord, { lineWidth: 0 }) : JSON.stringify(blankRecord, null, 2);
const content = useYAML
? yaml.stringify(blankRecord, { lineWidth: 0 })
: JSON.stringify(blankRecord, null, 2);
const done = writeFile(entryFilePath, content);
if (done) {
pkgContent.sprite = [entryFilePath_rel];
Expand Down
11 changes: 8 additions & 3 deletions src/lib/schema.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { z } from 'zod';

export const zString = (params?: z.RawCreateParams) => z.coerce.string(params).trim();
export const zString = (params?: z.RawCreateParams) =>
z.coerce.string(params).trim();

/** Name of the icon, (in lowercase) */
export const zIconName = zString({ message: 'invalid name' })
.regex(/^(?:[-a-z\d]*)$/, { message: 'invalid name, must be a kabab-case string' })
.regex(/^(?:[-a-z\d]*)$/, { message: 'invalid name, must be kebab-case' })
.min(1, { message: '"name" is required' })
.describe('Name of the icon, (should be in lowercase)');

Expand Down Expand Up @@ -45,7 +46,11 @@ export const zIconRecord = z
iconNamesSet.add(iconName);
continue;
}
ctx.addIssue({ code: 'custom', path: ctx.path, message: `icon name "${iconName}" is not unique` });
ctx.addIssue({
code: 'custom',
path: ctx.path,
message: `icon name "${iconName}" is not unique`,
});
break;
}
})
Expand Down
3 changes: 2 additions & 1 deletion src/lib/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export class SpriteStore {
constructor(record: SpriteRecord) {
const parsedRecord = zSpriteRecord.safeParse(record);
if (!parsedRecord.success) {
throw new SpriteError(parsedRecord.error.errors.map((e) => e.message).join(', '));
const errors = parsedRecord.error.errors.map((err) => err.message);
throw new SpriteError(errors.join(', '));
}
this.name = record.name;
this.prefix = record.prefix?.trim() || '';
Expand Down
26 changes: 19 additions & 7 deletions src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'node:fs';
import path from 'node:path';
import { zEntries, zSpriteRecord } from '@/lib/schema';
import { ResolvedConfig, SpriteConfig } from '@/types';
import fg from 'fast-glob';
import { globSync } from 'tinyglobby';
import YAML from 'yaml';
import { readFile, relativePath } from './files';
import { logger, SpriteError } from './logger';
Expand All @@ -29,17 +29,25 @@ export function resolveConfig(config: Partial<SpriteConfig>): ResolvedConfig {
}

/** Resolve sprite entries from glob patterns */
export function resolveEntries(srcA: SpriteEntries, srcB: SpriteEntries, cwd: string) {
export function resolveEntries(
srcA: SpriteEntries,
srcB: SpriteEntries,
cwd: string,
) {
// parse entries with zod
const entries = zEntries.safeParse(srcA).data || zEntries.safeParse(srcB).data;
const entries =
zEntries.safeParse(srcA).data || zEntries.safeParse(srcB).data;
if (!entries?.length) {
throw new SpriteError('no entries defined. Must use at least one entry');
}
// get all entries with fast-glob and filter
return fg.sync(entries, { cwd }).filter((entry) => {
return globSync(entries, { cwd }).filter((entry) => {
const { ext } = path.parse(entry);
if (!allowedConfigExtension.includes(ext)) {
logger.error(`invalid entry: ${relativePath(cwd, entry)}`, 'entries must end with .yaml, .yml or .json');
logger.error(
`invalid entry: ${relativePath(cwd, entry)}`,
'entries must end with .yaml, .yml or .json',
);
return false;
}
return true;
Expand All @@ -56,9 +64,13 @@ export function resolveRecord(entry: string, cwd: string) {
}
let rawRecord = {};
try {
rawRecord = /\.ya?ml/.test(entryFileExt) ? YAML.parse(content) : JSON.parse(content);
rawRecord = /\.ya?ml/.test(entryFileExt)
? YAML.parse(content)
: JSON.parse(content);
} catch {
throw new SpriteError(`unable to parse entry "${relativePath(cwd, entry)}"`);
throw new SpriteError(
`unable to parse entry "${relativePath(cwd, entry)}"`,
);
}
const parsedRecord = zSpriteRecord.safeParse(rawRecord);
if (parsedRecord.error) {
Expand Down
5 changes: 4 additions & 1 deletion src/utils/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { SpriteError } from './logger';
* @param targetPath - Path to directory
* @param isFilePath - Specify if the given target path is a file
*/
export function ensureDirectory(targetPath: string, isFilePath: boolean = false) {
export function ensureDirectory(
targetPath: string,
isFilePath: boolean = false,
) {
targetPath = isFilePath ? path.dirname(targetPath) : targetPath;
if (!fs.existsSync(targetPath)) {
fs.mkdirSync(targetPath, { recursive: true });
Expand Down