mirror of
https://github.com/LukeHagar/sveltesociety.dev.git
synced 2025-12-06 04:21:38 +00:00
feat: Add script to check if packages pass publint (#523)
* Add zod schemas for CI validation * Require npm field for components.json * Remove svelte-layout-resizable * Stricter Zod validation * Stricter repository field validation * Implement requested changes * Add back accidentally removed field * Move SvelteStore to templates.json * Update category and tags * Add script to get npm data * Add script to get publint data * Re-run updateNpm.js * Re-run updatePublint.js * Implement initial feedback * Use npm.json data * Update npm.js * Switch async/await to then/catch Co-authored-by: MacFJA <MacFJA@users.noreply.github.com> * Fix prettier * Run script * Re-run updateNpm * Also read tools.json * Add @types/node * Restructure npm.json output * Fix updatePublint.js * Display last update on components page * Add to weekly workflow * Clarify updating npm data * Update src/lib/utils/injectNpmData.ts Co-authored-by: MacFJA <MacFJA@users.noreply.github.com> * Smaller date font, add version * Improve error text * Fix property title * Move json to lib/data directory * Fix npm.json path * Also check tools.json * Add to automated PR * Add injectPublintData function * Update publint --------- Co-authored-by: MacFJA <MacFJA@users.noreply.github.com>
This commit is contained in:
6
.github/workflows/fetch-latest-data.yml
vendored
6
.github/workflows/fetch-latest-data.yml
vendored
@@ -25,6 +25,8 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Update npm data
|
||||
run: node scripts/updateNpm.js
|
||||
- name: Update publint data
|
||||
run: node scripts/updatePublint.js
|
||||
- name: Run format
|
||||
run: pnpm run format
|
||||
- name: Create Pull Request
|
||||
@@ -32,8 +34,8 @@ jobs:
|
||||
with:
|
||||
commit-message: "(AUTO) Update data"
|
||||
title: "🤖 Update data"
|
||||
body: Automatically fetch latest data from NPM, GitHub and GitLab
|
||||
body: Automatically fetch latest data from GitHub, GitLab, NPM and Publint.
|
||||
branch: ci-update-data
|
||||
add-paths: src/lib/data/npm.json,src/lib/data/stars.json
|
||||
add-paths: src/lib/data/npm.json,src/lib/data/publint.json,src/lib/data/stars.json
|
||||
delete-branch: true
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -30,12 +30,15 @@
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.35.1",
|
||||
"get-npm-tarball-url": "^2.1.0",
|
||||
"highlight.js": "^11.9.0",
|
||||
"itemsjs": "^2.1.24",
|
||||
"mdsvex": "^0.11.0",
|
||||
"package-name-regex": "^3.1.1",
|
||||
"pako": "^2.1.0",
|
||||
"prettier": "^3.1.1",
|
||||
"prettier-plugin-svelte": "^3.1.2",
|
||||
"publint": "^0.2.6",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"svelte": "^4.2.8",
|
||||
"svelte-check": "^3.6.2",
|
||||
|
||||
82
pnpm-lock.yaml
generated
82
pnpm-lock.yaml
generated
@@ -50,6 +50,9 @@ devDependencies:
|
||||
eslint-plugin-svelte:
|
||||
specifier: ^2.35.1
|
||||
version: 2.35.1(eslint@8.56.0)(svelte@4.2.8)
|
||||
get-npm-tarball-url:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
highlight.js:
|
||||
specifier: ^11.9.0
|
||||
version: 11.9.0
|
||||
@@ -62,12 +65,18 @@ devDependencies:
|
||||
package-name-regex:
|
||||
specifier: ^3.1.1
|
||||
version: 3.1.1
|
||||
pako:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
prettier:
|
||||
specifier: ^3.1.1
|
||||
version: 3.1.1
|
||||
prettier-plugin-svelte:
|
||||
specifier: ^3.1.2
|
||||
version: 3.1.2(prettier@3.1.1)(svelte@4.2.8)
|
||||
publint:
|
||||
specifier: ^0.2.6
|
||||
version: 0.2.6
|
||||
rehype-slug:
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0
|
||||
@@ -993,6 +1002,12 @@ packages:
|
||||
concat-map: 0.0.1
|
||||
dev: true
|
||||
|
||||
/brace-expansion@2.0.1:
|
||||
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
dev: true
|
||||
|
||||
/braces@3.0.2:
|
||||
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1488,6 +1503,11 @@ packages:
|
||||
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
|
||||
dev: true
|
||||
|
||||
/get-npm-tarball-url@2.1.0:
|
||||
resolution: {integrity: sha512-ro+DiMu5DXgRBabqXupW38h7WPZ9+Ad8UjwhvsmmN8w1sU7ab0nzAXvVZ4kqYg57OrqomRtJvepX5/xvFKNtjA==}
|
||||
engines: {node: '>=12.17'}
|
||||
dev: true
|
||||
|
||||
/get-stream@8.0.1:
|
||||
resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
|
||||
engines: {node: '>=16'}
|
||||
@@ -1522,6 +1542,17 @@ packages:
|
||||
path-is-absolute: 1.0.1
|
||||
dev: true
|
||||
|
||||
/glob@8.1.0:
|
||||
resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.4
|
||||
minimatch: 5.1.6
|
||||
once: 1.4.0
|
||||
dev: true
|
||||
|
||||
/globals@13.20.0:
|
||||
resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1590,6 +1621,13 @@ packages:
|
||||
safari-14-idb-fix: 1.0.6
|
||||
dev: true
|
||||
|
||||
/ignore-walk@5.0.1:
|
||||
resolution: {integrity: sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
dependencies:
|
||||
minimatch: 5.1.6
|
||||
dev: true
|
||||
|
||||
/ignore@5.2.4:
|
||||
resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
|
||||
engines: {node: '>= 4'}
|
||||
@@ -1807,6 +1845,13 @@ packages:
|
||||
brace-expansion: 1.1.11
|
||||
dev: true
|
||||
|
||||
/minimatch@5.1.6:
|
||||
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
dev: true
|
||||
|
||||
/minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
dev: true
|
||||
@@ -1862,6 +1907,29 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/npm-bundled@2.0.1:
|
||||
resolution: {integrity: sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
dependencies:
|
||||
npm-normalize-package-bin: 2.0.0
|
||||
dev: true
|
||||
|
||||
/npm-normalize-package-bin@2.0.0:
|
||||
resolution: {integrity: sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/npm-packlist@5.1.3:
|
||||
resolution: {integrity: sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
glob: 8.1.0
|
||||
ignore-walk: 5.0.1
|
||||
npm-bundled: 2.0.1
|
||||
npm-normalize-package-bin: 2.0.0
|
||||
dev: true
|
||||
|
||||
/npm-run-path@5.1.0:
|
||||
resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
@@ -1920,6 +1988,10 @@ packages:
|
||||
engines: {node: '>=14'}
|
||||
dev: true
|
||||
|
||||
/pako@2.1.0:
|
||||
resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==}
|
||||
dev: true
|
||||
|
||||
/parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -2094,6 +2166,16 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/publint@0.2.6:
|
||||
resolution: {integrity: sha512-zMwDVwrlLnCsviDXlczhuc5nIljsjZUgbLeKNyMYqbIJLRhcW81xrKsHlEu21YUaIxpa8T66tdIqP0mZm9ym3A==}
|
||||
engines: {node: '>=16'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
npm-packlist: 5.1.3
|
||||
picocolors: 1.0.0
|
||||
sade: 1.8.1
|
||||
dev: true
|
||||
|
||||
/punycode@2.3.0:
|
||||
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
44
scripts/tarball.js
Normal file
44
scripts/tarball.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// @ts-check
|
||||
// Source: https://github.com/bluwy/publint/blob/master/site/src/utils/tarball.js
|
||||
|
||||
/** @typedef {{ name: string, buffer: ArrayBuffer }} TarballFile */
|
||||
|
||||
/**
|
||||
* @param {TarballFile[]} files
|
||||
* @return {import('publint').Vfs}
|
||||
* */
|
||||
export function createTarballVfs(files) {
|
||||
return {
|
||||
getDirName: (path) => path.replace(/\/[^/]*$/, ''),
|
||||
getExtName: (path) => path.replace(/^.*\./, '.'),
|
||||
isPathDir: async (path) => {
|
||||
path = path.endsWith('/') ? path : path + '/';
|
||||
return files.some((file) => file.name.startsWith(path));
|
||||
},
|
||||
isPathExist: async (path) => {
|
||||
const pathDirVariant = path.endsWith('/') ? path : path + '/';
|
||||
return files.some((file) => file.name === path || file.name.startsWith(pathDirVariant));
|
||||
},
|
||||
pathJoin: (...parts) =>
|
||||
parts
|
||||
.map((v) => (v.startsWith('./') ? v.slice(2) : v))
|
||||
.join('/')
|
||||
.replace('///', '/')
|
||||
.replace('//', '/'), // TODO: optimize this please
|
||||
pathRelative: (from, to) => to.replace(from, '').slice(1),
|
||||
readDir: async (path) => {
|
||||
path = path.endsWith('/') ? path : path + '/';
|
||||
return files
|
||||
.filter((file) => file.name.startsWith(path) && file.name !== path)
|
||||
.map((file) => file.name.slice(path.length));
|
||||
},
|
||||
readFile: async (path) => {
|
||||
const file = files.find((file) => file.name === path);
|
||||
if (file) {
|
||||
return new TextDecoder('utf-8').decode(file.buffer);
|
||||
} else {
|
||||
throw new Error(`Unable to read file at path: ${path}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
306
scripts/untar.js
Normal file
306
scripts/untar.js
Normal file
@@ -0,0 +1,306 @@
|
||||
// @ts-check
|
||||
// Source: https://github.com/bluwy/publint/blob/master/site/src/utils/untar.js
|
||||
|
||||
export function untar(arrayBuffer) {
|
||||
const tarFileStream = new UntarFileStream(arrayBuffer);
|
||||
const files = [];
|
||||
while (tarFileStream.hasNext()) {
|
||||
const file = tarFileStream.next();
|
||||
files.push(file);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
// Source: https://gist.github.com/pascaldekloe/62546103a1576803dade9269ccf76330
|
||||
// Unmarshals an Uint8Array to string.
|
||||
function decodeUTF8(bytes) {
|
||||
var s = '';
|
||||
var i = 0;
|
||||
while (i < bytes.length) {
|
||||
var c = bytes[i++];
|
||||
if (c > 127) {
|
||||
if (c > 191 && c < 224) {
|
||||
if (i >= bytes.length) throw 'UTF-8 decode: incomplete 2-byte sequence';
|
||||
c = ((c & 31) << 6) | (bytes[i] & 63);
|
||||
} else if (c > 223 && c < 240) {
|
||||
if (i + 1 >= bytes.length) throw 'UTF-8 decode: incomplete 3-byte sequence';
|
||||
c = ((c & 15) << 12) | ((bytes[i] & 63) << 6) | (bytes[++i] & 63);
|
||||
} else if (c > 239 && c < 248) {
|
||||
if (i + 2 >= bytes.length) throw 'UTF-8 decode: incomplete 4-byte sequence';
|
||||
c =
|
||||
((c & 7) << 18) | ((bytes[i] & 63) << 12) | ((bytes[++i] & 63) << 6) | (bytes[++i] & 63);
|
||||
} else
|
||||
throw 'UTF-8 decode: unknown multibyte start 0x' + c.toString(16) + ' at index ' + (i - 1);
|
||||
++i;
|
||||
}
|
||||
|
||||
if (c <= 0xffff) s += String.fromCharCode(c);
|
||||
else if (c <= 0x10ffff) {
|
||||
c -= 0x10000;
|
||||
s += String.fromCharCode((c >> 10) | 0xd800);
|
||||
s += String.fromCharCode((c & 0x3ff) | 0xdc00);
|
||||
} else throw 'UTF-8 decode: code point 0x' + c.toString(16) + ' exceeds UTF-16 reach';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function PaxHeader(fields) {
|
||||
this._fields = fields;
|
||||
}
|
||||
|
||||
PaxHeader.parse = function (buffer) {
|
||||
// https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.bpxa500/paxex.htm
|
||||
// An extended header shall consist of one or more records, each constructed as follows:
|
||||
// "%d %s=%s\n", <length>, <keyword>, <value>
|
||||
|
||||
// The extended header records shall be encoded according to the ISO/IEC10646-1:2000 standard (UTF-8).
|
||||
// The <length> field, <blank>, equals sign, and <newline> shown shall be limited to the portable character set, as
|
||||
// encoded in UTF-8. The <keyword> and <value> fields can be any UTF-8 characters. The <length> field shall be the
|
||||
// decimal length of the extended header record in octets, including the trailing <newline>.
|
||||
|
||||
var bytes = new Uint8Array(buffer);
|
||||
var fields = [];
|
||||
|
||||
while (bytes.length > 0) {
|
||||
// Decode bytes up to the first space character; that is the total field length
|
||||
var fieldLength = parseInt(decodeUTF8(bytes.subarray(0, bytes.indexOf(0x20))));
|
||||
var fieldText = decodeUTF8(bytes.subarray(0, fieldLength));
|
||||
var fieldMatch = fieldText.match(/^\d+ ([^=]+)=(.*)\n$/);
|
||||
|
||||
if (fieldMatch === null) {
|
||||
throw new Error('Invalid PAX header data format.');
|
||||
}
|
||||
|
||||
var fieldName = fieldMatch[1];
|
||||
var fieldValue = fieldMatch[2];
|
||||
|
||||
if (fieldValue.length === 0) {
|
||||
fieldValue = null;
|
||||
} else if (fieldValue.match(/^\d+$/) !== null) {
|
||||
// If it's a integer field, parse it as int
|
||||
fieldValue = parseInt(fieldValue);
|
||||
}
|
||||
// Don't parse float values since precision is lost
|
||||
|
||||
var field = {
|
||||
name: fieldName,
|
||||
value: fieldValue
|
||||
};
|
||||
|
||||
fields.push(field);
|
||||
|
||||
bytes = bytes.subarray(fieldLength); // Cut off the parsed field data
|
||||
}
|
||||
|
||||
return new PaxHeader(fields);
|
||||
};
|
||||
|
||||
PaxHeader.prototype = {
|
||||
applyHeader: function (file) {
|
||||
// Apply fields to the file
|
||||
// If a field is of value null, it should be deleted from the file
|
||||
// https://www.mkssoftware.com/docs/man4/pax.4.asp
|
||||
|
||||
this._fields.forEach(function (field) {
|
||||
var fieldName = field.name;
|
||||
var fieldValue = field.value;
|
||||
|
||||
if (fieldName === 'path') {
|
||||
// This overrides the name and prefix fields in the following header block.
|
||||
fieldName = 'name';
|
||||
|
||||
if (file.prefix !== undefined) {
|
||||
delete file.prefix;
|
||||
}
|
||||
} else if (fieldName === 'linkpath') {
|
||||
// This overrides the linkname field in the following header block.
|
||||
fieldName = 'linkname';
|
||||
}
|
||||
|
||||
if (fieldValue === null) {
|
||||
delete file[fieldName];
|
||||
} else {
|
||||
file[fieldName] = fieldValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function UntarStream(arrayBuffer) {
|
||||
this._bufferView = new DataView(arrayBuffer);
|
||||
this._position = 0;
|
||||
}
|
||||
|
||||
UntarStream.prototype = {
|
||||
readString: function (charCount) {
|
||||
//console.log("readString: position " + this.position() + ", " + charCount + " chars");
|
||||
var charSize = 1;
|
||||
var byteCount = charCount * charSize;
|
||||
|
||||
var charCodes = [];
|
||||
|
||||
for (var i = 0; i < charCount; ++i) {
|
||||
var charCode = this._bufferView.getUint8(this.position() + i * charSize, true);
|
||||
if (charCode !== 0) {
|
||||
charCodes.push(charCode);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.seek(byteCount);
|
||||
|
||||
return String.fromCharCode.apply(null, charCodes);
|
||||
},
|
||||
|
||||
readBuffer: function (byteCount) {
|
||||
var buf;
|
||||
|
||||
if (typeof ArrayBuffer.prototype.slice === 'function') {
|
||||
buf = this._bufferView.buffer.slice(this.position(), this.position() + byteCount);
|
||||
} else {
|
||||
buf = new ArrayBuffer(byteCount);
|
||||
var target = new Uint8Array(buf);
|
||||
var src = new Uint8Array(this._bufferView.buffer, this.position(), byteCount);
|
||||
target.set(src);
|
||||
}
|
||||
|
||||
this.seek(byteCount);
|
||||
return buf;
|
||||
},
|
||||
|
||||
seek: function (byteCount) {
|
||||
this._position += byteCount;
|
||||
},
|
||||
|
||||
peekUint32: function () {
|
||||
return this._bufferView.getUint32(this.position(), true);
|
||||
},
|
||||
|
||||
position: function (newpos) {
|
||||
if (newpos === undefined) {
|
||||
return this._position;
|
||||
} else {
|
||||
this._position = newpos;
|
||||
}
|
||||
},
|
||||
|
||||
size: function () {
|
||||
return this._bufferView.byteLength;
|
||||
}
|
||||
};
|
||||
|
||||
function UntarFileStream(arrayBuffer) {
|
||||
this._stream = new UntarStream(arrayBuffer);
|
||||
this._globalPaxHeader = null;
|
||||
}
|
||||
|
||||
UntarFileStream.prototype = {
|
||||
hasNext: function () {
|
||||
// A tar file ends with 4 zero bytes
|
||||
return this._stream.position() + 4 < this._stream.size() && this._stream.peekUint32() !== 0;
|
||||
},
|
||||
|
||||
next: function () {
|
||||
return this._readNextFile();
|
||||
},
|
||||
|
||||
_readNextFile: function () {
|
||||
var stream = this._stream;
|
||||
var file = {};
|
||||
var isHeaderFile = false;
|
||||
var paxHeader = null;
|
||||
|
||||
var headerBeginPos = stream.position();
|
||||
var dataBeginPos = headerBeginPos + 512;
|
||||
|
||||
// Read header
|
||||
file.name = stream.readString(100);
|
||||
file.mode = stream.readString(8);
|
||||
file.uid = parseInt(stream.readString(8));
|
||||
file.gid = parseInt(stream.readString(8));
|
||||
file.size = parseInt(stream.readString(12), 8);
|
||||
file.mtime = parseInt(stream.readString(12), 8);
|
||||
file.checksum = parseInt(stream.readString(8));
|
||||
file.type = stream.readString(1);
|
||||
file.linkname = stream.readString(100);
|
||||
file.ustarFormat = stream.readString(6);
|
||||
|
||||
if (file.ustarFormat.indexOf('ustar') > -1) {
|
||||
file.version = stream.readString(2);
|
||||
file.uname = stream.readString(32);
|
||||
file.gname = stream.readString(32);
|
||||
file.devmajor = parseInt(stream.readString(8));
|
||||
file.devminor = parseInt(stream.readString(8));
|
||||
file.namePrefix = stream.readString(155);
|
||||
|
||||
if (file.namePrefix.length > 0) {
|
||||
file.name = file.namePrefix + '/' + file.name;
|
||||
}
|
||||
}
|
||||
|
||||
stream.position(dataBeginPos);
|
||||
|
||||
// Derived from https://www.mkssoftware.com/docs/man4/pax.4.asp
|
||||
// and https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/com.ibm.zos.v2r3.bpxa500/pxarchfm.htm
|
||||
switch (file.type) {
|
||||
case '0': // Normal file is either "0" or "\0".
|
||||
case '': // In case of "\0", readString returns an empty string, that is "".
|
||||
file.buffer = stream.readBuffer(file.size);
|
||||
break;
|
||||
case '1': // Link to another file already archived
|
||||
// TODO Should we do anything with these?
|
||||
break;
|
||||
case '2': // Symbolic link
|
||||
// TODO Should we do anything with these?
|
||||
break;
|
||||
case '3': // Character special device (what does this mean??)
|
||||
break;
|
||||
case '4': // Block special device
|
||||
break;
|
||||
case '5': // Directory
|
||||
break;
|
||||
case '6': // FIFO special file
|
||||
break;
|
||||
case '7': // Reserved
|
||||
break;
|
||||
case 'g': // Global PAX header
|
||||
isHeaderFile = true;
|
||||
this._globalPaxHeader = PaxHeader.parse(stream.readBuffer(file.size));
|
||||
break;
|
||||
case 'x': // PAX header
|
||||
isHeaderFile = true;
|
||||
paxHeader = PaxHeader.parse(stream.readBuffer(file.size));
|
||||
break;
|
||||
default: // Unknown file type
|
||||
break;
|
||||
}
|
||||
|
||||
if (file.buffer === undefined) {
|
||||
file.buffer = new ArrayBuffer(0);
|
||||
}
|
||||
|
||||
var dataEndPos = dataBeginPos + file.size;
|
||||
|
||||
// File data is padded to reach a 512 byte boundary; skip the padded bytes too.
|
||||
if (file.size % 512 !== 0) {
|
||||
dataEndPos += 512 - (file.size % 512);
|
||||
}
|
||||
|
||||
stream.position(dataEndPos);
|
||||
|
||||
if (isHeaderFile) {
|
||||
file = this._readNextFile();
|
||||
}
|
||||
|
||||
if (this._globalPaxHeader !== null) {
|
||||
this._globalPaxHeader.applyHeader(file);
|
||||
}
|
||||
|
||||
if (paxHeader !== null) {
|
||||
paxHeader.applyHeader(file);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
};
|
||||
77
scripts/updatePublint.js
Normal file
77
scripts/updatePublint.js
Normal file
@@ -0,0 +1,77 @@
|
||||
// @ts-check
|
||||
// Source: https://github.com/bluwy/publint/blob/master/site/src/utils/worker.js
|
||||
|
||||
import { writeFileSync } from 'node:fs';
|
||||
import { inflate } from 'pako';
|
||||
import getNpmTarballUrl from 'get-npm-tarball-url';
|
||||
import { componentsSchema, toolsSchema } from '../src/lib/schemas.js';
|
||||
import components from '../src/routes/components/components.json' assert { type: 'json' };
|
||||
import tools from '../src/routes/tools/tools.json' assert { type: 'json' };
|
||||
import npm from '../src/lib/data/npm.json' assert { type: 'json' };
|
||||
import { publint } from 'publint';
|
||||
import { untar } from './untar.js';
|
||||
import { createTarballVfs } from './tarball.js';
|
||||
|
||||
const dataWithoutVersions = [...componentsSchema.parse(components), ...toolsSchema.parse(tools)];
|
||||
|
||||
/** @param input {import('zod').infer<typeof toolsSchema>} */
|
||||
const injectVersions = (input) => {
|
||||
const output = [];
|
||||
for (const item of input) {
|
||||
/** @type {string} */
|
||||
const version = npm[item.npm]?.version;
|
||||
if (version) {
|
||||
output.push({ ...item, version });
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
const dataWithVersions = injectVersions(dataWithoutVersions);
|
||||
|
||||
const output = await Promise.all(
|
||||
dataWithVersions.map(async (pkg) => {
|
||||
try {
|
||||
return await processPackage(pkg);
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
}
|
||||
})
|
||||
).then((values) => {
|
||||
let versions = {};
|
||||
for (const value of values) {
|
||||
if (value) {
|
||||
versions[value.name] = value.valid;
|
||||
}
|
||||
}
|
||||
return versions;
|
||||
});
|
||||
|
||||
writeFileSync('src/lib/data/publint.json', JSON.stringify(output));
|
||||
|
||||
/** @param pkg {ReturnType<typeof injectVersions>[0]} */
|
||||
async function processPackage(pkg) {
|
||||
const tarballUrl = getNpmTarballUrl(pkg.npm, pkg.version);
|
||||
let resultBuffer;
|
||||
try {
|
||||
const result = await fetch(tarballUrl);
|
||||
resultBuffer = await result.arrayBuffer();
|
||||
} catch (e) {
|
||||
postMessage({ type: 'error', data: 'Package not found' });
|
||||
console.error(e);
|
||||
}
|
||||
let files;
|
||||
try {
|
||||
const tarBuffer = inflate(resultBuffer).buffer; // Handles gzip (gz)
|
||||
files = untar(tarBuffer); // Handles tar (t)
|
||||
} catch (e) {
|
||||
postMessage({ type: 'error', data: 'Failed to unpack package' });
|
||||
console.error(e);
|
||||
return;
|
||||
}
|
||||
const vfs = createTarballVfs(files);
|
||||
|
||||
const pkgDir = files.length ? files[0].name.split('/')[0] : 'package';
|
||||
const { messages } = await publint({ pkgDir, vfs, level: 'warning' });
|
||||
return { name: pkg.npm, valid: messages.length === 0 };
|
||||
}
|
||||
366
src/lib/data/publint.json
Normal file
366
src/lib/data/publint.json
Normal file
@@ -0,0 +1,366 @@
|
||||
{
|
||||
"svelte-stopwatch": true,
|
||||
"curseur": true,
|
||||
"svelte-zod-form": true,
|
||||
"svelte-selecto": false,
|
||||
"svelte-pilot": true,
|
||||
"super-sitemap": true,
|
||||
"svelte-scrollactive": true,
|
||||
"svelte-tel-input": true,
|
||||
"svault": true,
|
||||
"svelte-datatables-net": true,
|
||||
"stwui": false,
|
||||
"@sveltejs/adapter-auto": true,
|
||||
"@sveltejs/adapter-netlify": true,
|
||||
"@sveltejs/adapter-cloudflare-workers": true,
|
||||
"@sveltejs/adapter-cloudflare": true,
|
||||
"@sveltejs/adapter-node": true,
|
||||
"@sveltejs/adapter-static": true,
|
||||
"@sveltejs/adapter-vercel": true,
|
||||
"svelte-lazy-loader": true,
|
||||
"svelte-carbonbadge": true,
|
||||
"svelte-form-validation": true,
|
||||
"date-picker-svelte": true,
|
||||
"svelte-virtual-table": false,
|
||||
"svelte-number-spinner": false,
|
||||
"svelte-remixicon": true,
|
||||
"svelte-fast-marquee": true,
|
||||
"sswr": false,
|
||||
"svelte-adapter-firebase": true,
|
||||
"@architect/sveltekit-adapter": true,
|
||||
"svelte-adapter-deno": true,
|
||||
"svelte-client-router": false,
|
||||
"felte": false,
|
||||
"sveltefire": true,
|
||||
"svelte-time-picker": true,
|
||||
"svelte-formula": false,
|
||||
"svelte-calendar": true,
|
||||
"svelte-tags-input": false,
|
||||
"sveltedoc-parser": true,
|
||||
"aovi-svelte": false,
|
||||
"svelte-chota": false,
|
||||
"svelte-eventbus": false,
|
||||
"tinro": false,
|
||||
"fa-svelte": true,
|
||||
"svelte-fullscreen": true,
|
||||
"svelte-grid-responsive": false,
|
||||
"svelte-infinite-scroll": true,
|
||||
"svelte-formly": true,
|
||||
"svelte-websocket-store": true,
|
||||
"sveltestrap": false,
|
||||
"@beyonk/gdpr-cookie-consent-banner": true,
|
||||
"@beyonk/svelte-carousel": true,
|
||||
"@beyonk/svelte-facebook-customer-chat": true,
|
||||
"@beyonk/svelte-facebook-pixel": false,
|
||||
"@beyonk/svelte-google-analytics": false,
|
||||
"@beyonk/svelte-googlemaps": false,
|
||||
"@beyonk/svelte-mapbox": true,
|
||||
"@beyonk/svelte-notifications": true,
|
||||
"@beyonk/svelte-scrollspy": false,
|
||||
"svelte-simple-icons": false,
|
||||
"@beyonk/svelte-trustpilot": true,
|
||||
"@bjornlu/svelte-router": false,
|
||||
"svelte-sortable-list": true,
|
||||
"svelte-data-grid": false,
|
||||
"query-store": true,
|
||||
"svelma": false,
|
||||
"svelte-forms": true,
|
||||
"svelte-credit-cards": false,
|
||||
"svelte-headroom": false,
|
||||
"svelte-fa": false,
|
||||
"svelte-table": false,
|
||||
"svelte-moveable": true,
|
||||
"svelte-ruler": false,
|
||||
"waxwing-rating": true,
|
||||
"@dopry/svelte-auth0": false,
|
||||
"svelte-feather-icons": false,
|
||||
"@easylogic/svelte-summernote": false,
|
||||
"svelte-dev-helper": false,
|
||||
"svelte-routing": false,
|
||||
"svelte-rate-it": true,
|
||||
"@equipmentshare/date-range-input": true,
|
||||
"svelte-tree": false,
|
||||
"svelteify": true,
|
||||
"svelte-simple-modal": true,
|
||||
"@urql/svelte": false,
|
||||
"svelte-icons": false,
|
||||
"svelte-native": false,
|
||||
"svelte-copyright": true,
|
||||
"svelte-flex": true,
|
||||
"svelte-frappe-charts": false,
|
||||
"svelte-material-ui": true,
|
||||
"@ikun-ui/core": false,
|
||||
"carbon-components-svelte": false,
|
||||
"attractions": false,
|
||||
"svelte-spa-router": true,
|
||||
"svelte-flatpickr": false,
|
||||
"svelte-navaid": false,
|
||||
"@jamen/svelte-router": false,
|
||||
"svelte-router": true,
|
||||
"svelte-pick-a-place": false,
|
||||
"svelte-tabs": false,
|
||||
"svelteml": false,
|
||||
"svelte-compare-image-slider": false,
|
||||
"svelte-router-spa": false,
|
||||
"svelte-css-vars": true,
|
||||
"svelte-i18n": true,
|
||||
"@nubolab-ffwd/svelte-fluent": true,
|
||||
"svelte-loadable": true,
|
||||
"svero": false,
|
||||
"svelte-notifications": false,
|
||||
"svelte-fragment-component": false,
|
||||
"svelte-htm": false,
|
||||
"svelte-jsx": true,
|
||||
"svelte-favicon-badge": false,
|
||||
"svelte-redux-connect": false,
|
||||
"svelte-jester": true,
|
||||
"svelte-jest": true,
|
||||
"echarts-for-svelte": false,
|
||||
"@lottiefiles/svelte-lottie-player": false,
|
||||
"@pwa/cli": false,
|
||||
"svelte-inview": true,
|
||||
"smelte": false,
|
||||
"@melt-ui/svelte": true,
|
||||
"radix-svelte": true,
|
||||
"svelte-image": true,
|
||||
"svelte-waypoint": false,
|
||||
"sveltejs-forms": false,
|
||||
"svelte-navigator": false,
|
||||
"layercake": true,
|
||||
"@egjs/svelte-infinitegrid": false,
|
||||
"svelte-page-progress": false,
|
||||
"@okrad/svelte-progressbar": true,
|
||||
"svelte-intl": false,
|
||||
"svql": false,
|
||||
"yrv": false,
|
||||
"svelte-asyncable": false,
|
||||
"svelte-content-loader": false,
|
||||
"svelte-image-compare": false,
|
||||
"svelte-imask": false,
|
||||
"svelte-page-router": true,
|
||||
"svelte-pathfinder": false,
|
||||
"svelte-ticker": false,
|
||||
"svelte-viewpoint": false,
|
||||
"select-madu": true,
|
||||
"svelte-match-media": false,
|
||||
"svelte-webext-storage-adapter": true,
|
||||
"svelte-writable-derived": false,
|
||||
"storez": true,
|
||||
"svelte-adapter": false,
|
||||
"svelte-test": false,
|
||||
"svelte-fusioncharts": false,
|
||||
"simple-svelte-autocomplete": true,
|
||||
"svelte-hash-router": false,
|
||||
"svelte-color-picker": false,
|
||||
"svelte-inspector": true,
|
||||
"swheel": false,
|
||||
"svelte-accessible-dialog": false,
|
||||
"@sveltejs/pancake": true,
|
||||
"svelte-select": true,
|
||||
"svelte-awesome": true,
|
||||
"jest-transform-svelte": false,
|
||||
"svelte-image-encoder": true,
|
||||
"multicarousel": false,
|
||||
"svelte-heatmap": false,
|
||||
"svelte-swipe": true,
|
||||
"@slick-for/svelte": true,
|
||||
"svelte-marquee": false,
|
||||
"svelte-range-slider-pips": false,
|
||||
"svelte-infinite-loading": false,
|
||||
"@spaceavocado/svelte-form": false,
|
||||
"@spaceavocado/svelte-router": false,
|
||||
"svelte-multitoneimage": true,
|
||||
"@storybook/sveltekit": false,
|
||||
"@storybook/svelte": false,
|
||||
"svelte-toolbox": false,
|
||||
"routify": false,
|
||||
"@sveltejs/gestures": true,
|
||||
"@sveltejs/gl": false,
|
||||
"@sveltejs/svelte-repl": false,
|
||||
"@sveltejs/svelte-scroller": true,
|
||||
"@sveltejs/svelte-subdivide": false,
|
||||
"@sveltejs/svelte-virtual-list": true,
|
||||
"svelte-virtual-list-ce": true,
|
||||
"svelte-state-renderer": true,
|
||||
"@testing-library/svelte": true,
|
||||
"svelte-file-dropzone": true,
|
||||
"svelte-apollo": true,
|
||||
"svelte-observable": false,
|
||||
"sveltemantic": false,
|
||||
"svelte-forms-lib": false,
|
||||
"svelte-grid": false,
|
||||
"svelte-popover": true,
|
||||
"svelte-easy-crop": true,
|
||||
"svelte-mui": false,
|
||||
"s-offline": true,
|
||||
"minna-ui": true,
|
||||
"shadcn-svelte": true,
|
||||
"svelte-headlessui": true,
|
||||
"svelte-media-query": true,
|
||||
"svelte-mobx": false,
|
||||
"svelte-input-mask": true,
|
||||
"svelidation": false,
|
||||
"svelte-fullcalendar": true,
|
||||
"svelte-item-list": true,
|
||||
"@zooplus/zoo-web-components": true,
|
||||
"svelte-atoms": false,
|
||||
"overmind-svelte": false,
|
||||
"svelte-tiny-virtual-list": false,
|
||||
"@svelte-parts/drop-file": true,
|
||||
"@svelte-parts/form": true,
|
||||
"@svelte-parts/icons": false,
|
||||
"@svelte-parts/zoom": true,
|
||||
"svelte-appwrite": false,
|
||||
"svelte-pdf": true,
|
||||
"svelte-micro": true,
|
||||
"svantic": true,
|
||||
"@macfja/svelte-undoable": true,
|
||||
"renderless-svelte": false,
|
||||
"svate": false,
|
||||
"svelte-parallax": false,
|
||||
"svelte-modals": true,
|
||||
"@macfja/svelte-persistent-store": false,
|
||||
"@macfja/svelte-invalidable": true,
|
||||
"svelte-carousel": true,
|
||||
"svelte-restate": true,
|
||||
"svelte-pincode": true,
|
||||
"svelte-particles": true,
|
||||
"svelte-tiptap": true,
|
||||
"spaper": true,
|
||||
"@event-calendar/core": true,
|
||||
"@kahi-ui/framework": true,
|
||||
"@macfja/svelte-multi-adapter": true,
|
||||
"svelte-multiselect": true,
|
||||
"svelte-toc": true,
|
||||
"svelte-bricks": true,
|
||||
"@macfja/svelte-oauth2": false,
|
||||
"svelte-boring-avatars": false,
|
||||
"filedrop-svelte": true,
|
||||
"focus-svelte": true,
|
||||
"svelte-translate": false,
|
||||
"svelecte": false,
|
||||
"svelte-adapter-azure-swa": true,
|
||||
"svelte-adapter-appengine": true,
|
||||
"sveltekit-adapter-browser-extension": true,
|
||||
"svelte-fsm": true,
|
||||
"@yellowinq/svelte-pin-input": true,
|
||||
"svelte-codesandbox": true,
|
||||
"svelte-icons-pack": false,
|
||||
"@joeinnes/svelte-image": true,
|
||||
"@budgetdraw/sveltekit-cloudflare-adapter": true,
|
||||
"svelte-intl-precompile": true,
|
||||
"svelte-cleavejs": false,
|
||||
"svelty-picker": true,
|
||||
"svelte-slider": false,
|
||||
"sveltekit-adapter-wordpress-shortcode": true,
|
||||
"@macfja/svelte-expirable": false,
|
||||
"svelte-store2": true,
|
||||
"@macfja/svelte-adapter-neutralino": true,
|
||||
"sveltekit-adapter-html-like": true,
|
||||
"svelte-gestures": false,
|
||||
"svelte-adapter-github": true,
|
||||
"svelte-steps": true,
|
||||
"agnostic-svelte": true,
|
||||
"svelte-adapter-static-digitalocean": true,
|
||||
"@kitql/all-in": true,
|
||||
"svelte-brick-gallery": true,
|
||||
"svelte-adapter-bun": true,
|
||||
"@rgossiaux/svelte-headlessui": true,
|
||||
"@brewer/beerui": false,
|
||||
"@skeletonlabs/skeleton": true,
|
||||
"svelte-hover-draw-svg": true,
|
||||
"casual-ui-svelte": true,
|
||||
"@specialdoom/proi-ui": false,
|
||||
"@canutin/svelte-currency-input": true,
|
||||
"flowbite-svelte": true,
|
||||
"typesafe-i18n": false,
|
||||
"@tolgee/svelte": true,
|
||||
"sthemer": false,
|
||||
"svelte-exstore": true,
|
||||
"@macfja/svelte-scroll-video": true,
|
||||
"@prgm/sveltekit-progress-bar": true,
|
||||
"svelte-unicons": false,
|
||||
"svelte-google-auth": true,
|
||||
"sveltekit-adapter-firebase": true,
|
||||
"sveltekit-search-params": true,
|
||||
"@geoffcox/sterling-svelte": true,
|
||||
"simple-ui-components-in-svelte": true,
|
||||
"@tanstack/svelte-query": true,
|
||||
"@pragmatic-engineering/svelte-form-builder-community": true,
|
||||
"@ptkdev/sveltekit-cordova-adapter": true,
|
||||
"@ptkdev/sveltekit-electron-adapter": true,
|
||||
"@carlosv2/adapter-node-ws": true,
|
||||
"leblog": true,
|
||||
"html-svelte-parser": true,
|
||||
"svelte-droplet": true,
|
||||
"chat-embed": true,
|
||||
"lucide-svelte": false,
|
||||
"yesvelte": true,
|
||||
"@bonosoft/sveltekit-qrcode": true,
|
||||
"@bonosoft/sveltekit-progress": true,
|
||||
"@radar-azdelta/svelte-datatable": true,
|
||||
"svelte-svg-transform": true,
|
||||
"@nerd-coder/svelte-zod-form": true,
|
||||
"sveltekit-adapter-iis": true,
|
||||
"svelte-dx-table": false,
|
||||
"svelte-switch": false,
|
||||
"svelte-pagination": false,
|
||||
"stdf": true,
|
||||
"@twicpics/components": false,
|
||||
"@shipbit/svane": true,
|
||||
"sveltekit-html-minifier": true,
|
||||
"svelte-tex": false,
|
||||
"drab": true,
|
||||
"supasveltekit": true,
|
||||
"@jill64/sveltekit-adapter-aws": true,
|
||||
"sveltekit-adapter-versioned-worker": true,
|
||||
"layerchart": true,
|
||||
"@egjs/svelte-flicking": false,
|
||||
"svelte-ux": true,
|
||||
"@born05/sveltekit-proxy": true,
|
||||
"@mismerge/core": true,
|
||||
"svelte-ripple-action": true,
|
||||
"sveltekit-superforms": true,
|
||||
"svelte-reparent": true,
|
||||
"svelte-inline-modal": true,
|
||||
"@tanstack/svelte-table": false,
|
||||
"@histoire/plugin-svelte": true,
|
||||
"lucia": true,
|
||||
"@monaco-auth/sveltekit": true,
|
||||
"trpc-svelte-query": true,
|
||||
"svelte-legos": false,
|
||||
"@supabase/auth-helpers-sveltekit": true,
|
||||
"svelte-markdown": false,
|
||||
"svelte-exmarkdown": true,
|
||||
"@sentry/svelte": false,
|
||||
"svelte-french-toast": true,
|
||||
"@zerodevx/svelte-toast": true,
|
||||
"@mavthedev/svodals": true,
|
||||
"rollup-plugin-svelte": true,
|
||||
"svelte-loader": false,
|
||||
"@sveltejs/vite-plugin-svelte": true,
|
||||
"esbuild-svelte": true,
|
||||
"rollup-plugin-svelte-hot": true,
|
||||
"parcel-transformer-svelte3-plus": true,
|
||||
"parcel-plugin-svelte": true,
|
||||
"sveltify": true,
|
||||
"gulp-svelte": true,
|
||||
"sveltejs-brunch": true,
|
||||
"svelte-preprocess": true,
|
||||
"svelte-preprocess-markdown": true,
|
||||
"mdsvex": false,
|
||||
"svelte-preprocess-less": false,
|
||||
"svelte-switch-case": true,
|
||||
"@modular-css/svelte": true,
|
||||
"svelte-preprocess-sass": false,
|
||||
"svelte-preprocess-css-hash": true,
|
||||
"svelte-preprocess-html-asset": true,
|
||||
"svelte-preprocessor-fetch": false,
|
||||
"prettier-plugin-svelte": true,
|
||||
"svelte-check": true,
|
||||
"svelte-reactive-css-preprocess": true,
|
||||
"svelte-subcomponent-preprocessor": true,
|
||||
"eslint-plugin-svelte": true,
|
||||
"full-client-server-sveltekit": true,
|
||||
"svelte-preprocess-delegate-events": true
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import npm from '$lib/data/npm.json';
|
||||
import publint from '$lib/data/publint.json';
|
||||
import type { z } from 'zod';
|
||||
import type { componentsSchema } from '$lib/schemas';
|
||||
|
||||
@@ -10,3 +11,12 @@ export const injectNpmData = (input: z.infer<typeof componentsSchema>) => {
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
export const injectPublintData = (input: z.infer<typeof componentsSchema>) => {
|
||||
const output = [];
|
||||
for (const item of input) {
|
||||
const extra = publint[item.npm] ?? false;
|
||||
output.push({ ...item, publint: extra });
|
||||
}
|
||||
return output;
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import components from './components.json';
|
||||
import SearchableJson from '$lib/SearchableJson.svelte';
|
||||
import { injectNpmData } from '$utils/injectNpmData';
|
||||
import { injectNpmData } from '$utils/injectData';
|
||||
import { injectStars } from '$utils/stars';
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import tools from '../tools/tools.json';
|
||||
import SearchableJson from '$lib/SearchableJson.svelte';
|
||||
import { injectNpmData } from '$utils/injectNpmData';
|
||||
import { injectNpmData } from '$utils/injectData';
|
||||
import { injectStars } from '$utils/stars';
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user