diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 0e3a68b8..e80e6900 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -21,7 +21,6 @@ jobs: - uses: actions/checkout@v4 - run: make lint - run: make test - - run: make dist - run: ./scripts/ci-quality-no-uncommitted-files.sh - run: gh config set prompt disabled @@ -31,10 +30,6 @@ jobs: - name: Perform Tag Release run: | gh release create ${{ github.ref_name }} --draft=false --title ${{ github.ref_name }} --target "$GITHUB_SHA" --generate-notes - gh release upload --clobber ${{ github.ref_name }} dist/*.zip dist/*.tar.gz if: github.ref_type == 'tag' env: GH_TOKEN: ${{ github.token }} - - - name: Publish to NPM - run: sudo npm install --global npm@latest && npm publish diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ff27840..e0e4191d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,5 +20,4 @@ jobs: - uses: actions/checkout@v4 - run: make lint - run: make test - - run: make dist - run: ./scripts/ci-quality-no-uncommitted-files.sh diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 4c27a088..00000000 --- a/.npmignore +++ /dev/null @@ -1,9 +0,0 @@ -* -!LICENSE -!README.markdown -!schemas -!schemas/** -!npm -!npm/** -npm/**/*.test.js -npm/**/*.test.mjs diff --git a/Makefile b/Makefile index e2c2717b..3b80b791 100644 --- a/Makefile +++ b/Makefile @@ -40,25 +40,6 @@ lint: common node_modules .PHONY: test test: node_modules $(TIME) $(NODE) $(JSONSCHEMA) test ./test - $(NODE) npm/cjs.test.js - $(NODE) npm/esm.test.mjs - -# TODO: Add a `jsonschema pkg` command instead -.PHONY: dist -VERSION = $(shell $(JQ) --raw-output '.["x-version"]' jsonschema.json) -dist: - $(RMRF) $@ - $(MKDIRP) $@ - cd schemas && $(ZIP) -r ../$@/sourcemeta-std-v$(VERSION).zip * -x '*.DS_Store' - $(ZIP) $@/sourcemeta-std-v$(VERSION).zip LICENSE - $(UNZIP) -l $@/sourcemeta-std-v$(VERSION).zip - cd schemas && $(TAR) -cf ../$@/sourcemeta-std-v$(VERSION).tar --exclude '.DS_Store' * - $(TAR) -rf $@/sourcemeta-std-v$(VERSION).tar LICENSE - $(GZIP) $@/sourcemeta-std-v$(VERSION).tar - $(TAR) -tzf $@/sourcemeta-std-v$(VERSION).tar.gz - $(MKDIRP) $@/npm - $(NPM) version --no-git-tag-version --allow-same-version "$(VERSION)" - $(NPM) pack --pack-destination $@/npm node_modules: package.json package-lock.json $(NPM) ci diff --git a/README.markdown b/README.markdown index 6c675801..6508cdfa 100644 --- a/README.markdown +++ b/README.markdown @@ -2,7 +2,6 @@ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.17526561.svg)](https://doi.org/10.5281/zenodo.17526561) [![GitHub Release](https://img.shields.io/github/v/release/sourcemeta/std)](https://github.com/sourcemeta/std/releases) -[![NPM Version](https://img.shields.io/npm/v/@sourcemeta/std)](https://www.npmjs.com/package/@sourcemeta/std) *** **Browse the schemas at [https://schemas.sourcemeta.com/sourcemeta/std](https://schemas.sourcemeta.com/sourcemeta/std)** diff --git a/meta/schemas.json b/meta/schemas.json index 0ddb9c44..417c2072 100644 --- a/meta/schemas.json +++ b/meta/schemas.json @@ -15,13 +15,19 @@ "properties": { "$id": false, "$comment": { - "$ref": "../schemas/2020-12/misc/single-line-text.json" + "$ref": "#/$defs/single-line-text" }, "title": { - "$ref": "../schemas/2020-12/misc/single-line-text.json" + "$ref": "#/$defs/single-line-text" }, "description": { - "$ref": "../schemas/2020-12/misc/single-line-text.json" + "$ref": "#/$defs/single-line-text" + } + }, + "$defs": { + "single-line-text": { + "type": "string", + "pattern": "^(?!.*\\.$)(?!.*(? { - const schema = getSchema('2020-12/misc/schema-like'); - assert.strictEqual(typeof schema, 'object'); - assert.strictEqual(schema.$schema, 'https://json-schema.org/draft/2020-12/schema'); - assert.strictEqual(schema.title, 'JSON Schema Document'); -}); - -test('returns null for non-existent schema', () => { - const schema = getSchema('nonexistent/schema/path'); - assert.strictEqual(schema, null); -}); - -test('returns null for invalid input types', () => { - assert.strictEqual(getSchema(null), null); - assert.strictEqual(getSchema(undefined), null); - assert.strictEqual(getSchema(123), null); - assert.strictEqual(getSchema({}), null); -}); - -test('blocks directory traversal attempts', () => { - const schema = getSchema('../package'); - assert.strictEqual(schema, null); -}); - -test('blocks directory traversal with multiple levels', () => { - const schema = getSchema('../../etc/passwd'); - assert.strictEqual(schema, null); -}); - -test('loads schema from nested path', () => { - const schema = getSchema('2020-12/w3c/xmlschema/2001/hex-binary'); - assert.strictEqual(typeof schema, 'object'); - assert.strictEqual(schema.$schema, 'https://json-schema.org/draft/2020-12/schema'); -}); - -test('lazy loads schema via schemas object', () => { - const { schemas } = require('..'); - const schema = schemas['2020-12'].misc['schema-like']; - assert.strictEqual(typeof schema, 'object'); - assert.strictEqual(schema.title, 'JSON Schema Document'); -}); - -test('caches loaded schemas', () => { - const { schemas } = require('..'); - const schema1 = schemas['2020-12'].misc['schema-like']; - const schema2 = schemas['2020-12'].misc['schema-like']; - assert.strictEqual(schema1, schema2); -}); - -test('handles deeply nested paths', () => { - const { schemas } = require('..'); - const schema = schemas['2020-12'].w3c.xmlschema['2001']['hex-binary']; - assert.strictEqual(typeof schema, 'object'); - assert.strictEqual(schema.$schema, 'https://json-schema.org/draft/2020-12/schema'); -}); - -test('returns undefined for non-existent directories', () => { - const { schemas } = require('..'); - const result = schemas['2020-12'].nonexistent; - assert.strictEqual(result, undefined); -}); - -test('returns undefined for non-existent files', () => { - const { schemas } = require('..'); - const result = schemas['2020-12'].misc['nonexistent-file']; - assert.strictEqual(result, undefined); -}); diff --git a/npm/esm.test.mjs b/npm/esm.test.mjs deleted file mode 100644 index 0b2cf203..00000000 --- a/npm/esm.test.mjs +++ /dev/null @@ -1,66 +0,0 @@ -import test from 'node:test'; -import assert from 'node:assert'; -import getSchema, { schemas } from '@sourcemeta/std'; - -test('loads a valid schema', () => { - const schema = getSchema('2020-12/misc/schema-like'); - assert.strictEqual(typeof schema, 'object'); - assert.strictEqual(schema.$schema, 'https://json-schema.org/draft/2020-12/schema'); - assert.strictEqual(schema.title, 'JSON Schema Document'); -}); - -test('returns null for non-existent schema', () => { - const schema = getSchema('nonexistent/schema/path'); - assert.strictEqual(schema, null); -}); - -test('returns null for invalid input types', () => { - assert.strictEqual(getSchema(null), null); - assert.strictEqual(getSchema(undefined), null); - assert.strictEqual(getSchema(123), null); - assert.strictEqual(getSchema({}), null); -}); - -test('blocks directory traversal attempts', () => { - const schema = getSchema('../package'); - assert.strictEqual(schema, null); -}); - -test('blocks directory traversal with multiple levels', () => { - const schema = getSchema('../../etc/passwd'); - assert.strictEqual(schema, null); -}); - -test('loads schema from nested path', () => { - const schema = getSchema('2020-12/w3c/xmlschema/2001/hex-binary'); - assert.strictEqual(typeof schema, 'object'); - assert.strictEqual(schema.$schema, 'https://json-schema.org/draft/2020-12/schema'); -}); - -test('lazy loads schema via schemas object', () => { - const schema = schemas['2020-12'].misc['schema-like']; - assert.strictEqual(typeof schema, 'object'); - assert.strictEqual(schema.title, 'JSON Schema Document'); -}); - -test('caches loaded schemas', () => { - const schema1 = schemas['2020-12'].misc['schema-like']; - const schema2 = schemas['2020-12'].misc['schema-like']; - assert.strictEqual(schema1, schema2); -}); - -test('handles deeply nested paths', () => { - const schema = schemas['2020-12'].w3c.xmlschema['2001']['hex-binary']; - assert.strictEqual(typeof schema, 'object'); - assert.strictEqual(schema.$schema, 'https://json-schema.org/draft/2020-12/schema'); -}); - -test('returns undefined for non-existent directories', () => { - const result = schemas['2020-12'].nonexistent; - assert.strictEqual(result, undefined); -}); - -test('returns undefined for non-existent files', () => { - const result = schemas['2020-12'].misc['nonexistent-file']; - assert.strictEqual(result, undefined); -}); diff --git a/npm/main.js b/npm/main.js deleted file mode 100644 index f8bca959..00000000 --- a/npm/main.js +++ /dev/null @@ -1,65 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -function getSchema(schemaPath) { - if (!schemaPath || typeof schemaPath !== 'string') { - return null; - } - - if (schemaPath.includes('..')) { - return null; - } - - const absolutePath = path.join(__dirname, '..', 'schemas', `${schemaPath}.json`); - - try { - const content = fs.readFileSync(absolutePath, 'utf8'); - return JSON.parse(content); - } catch (error) { - return null; - } -} - -const cache = new Map(); - -function createSchemaProxy(currentPath = '') { - return new Proxy({}, { - get(target, property) { - if (typeof property !== 'string') { - return undefined; - } - - const newPath = currentPath ? `${currentPath}/${property}` : property; - - if (cache.has(newPath)) { - return cache.get(newPath); - } - - const schemaBasePath = path.join(__dirname, '..', 'schemas'); - const fullPath = path.join(schemaBasePath, newPath); - - const jsonPath = `${fullPath}.json`; - if (fs.existsSync(jsonPath)) { - try { - const content = fs.readFileSync(jsonPath, 'utf8'); - const schema = JSON.parse(content); - cache.set(newPath, schema); - return schema; - } catch (error) { - return undefined; - } - } - - if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) { - const proxy = createSchemaProxy(newPath); - cache.set(newPath, proxy); - return proxy; - } - - return undefined; - } - }); -} - -module.exports = getSchema; -module.exports.schemas = createSchemaProxy(); diff --git a/npm/main.mjs b/npm/main.mjs deleted file mode 100644 index 93be0bf5..00000000 --- a/npm/main.mjs +++ /dev/null @@ -1,7 +0,0 @@ -import { createRequire } from 'node:module'; - -const require = createRequire(import.meta.url); -const getSchema = require('./main.js'); - -export const schemas = getSchema.schemas; -export default getSchema; diff --git a/package.json b/package.json index df132a6f..5c98b957 100644 --- a/package.json +++ b/package.json @@ -1,55 +1,7 @@ { "name": "@sourcemeta/std", - "version": "0.3.1", - "description": "A growing collection of hand-crafted high-quality schemas, From RFC-compliant Email Address schemas to ISO-compliant Currency Codes", - "main": "npm/main.js", - "module": "npm/main.mjs", - "exports": { - ".": { - "import": "./npm/main.mjs", - "require": "./npm/main.js" - } - }, - "license": "UNLICENSED", - "homepage": "https://github.com/sourcemeta/std", - "author": { - "email": "hello@sourcemeta.com", - "name": "Sourcemeta", - "url": "https://www.sourcemeta.com" - }, - "funding": "https://github.com/sponsors/sourcemeta", - "keywords": [ - "jsonschema", - "json", - "schema", - "json-schema", - "cli", - "$ref", - "dereference", - "reference", - "resolve", - "json-pointer", - "validator", - "validation", - "bundle", - "json-schema-validator", - "json-schema-validation", - "lint", - "format", - "draft", - "library" - ], - "bugs": { - "url": "https://github.com/sourcemeta/std/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/sourcemeta/std.git" - }, - "publishConfig": { - "provenance": true, - "access": "public" - }, + "version": "0.0.0", + "private": true, "devDependencies": { "@sourcemeta/jsonschema": "^13.2.0" } diff --git a/schemas/2020-12/misc/schema-like.json b/schemas/2020-12/misc/schema-like.json deleted file mode 100644 index 7ca0507d..00000000 --- a/schemas/2020-12/misc/schema-like.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "JSON Schema Document", - "description": "A JSON document that is considered to be a potentially valid JSON Schema", - "examples": [ - true, - false, - { - "type": "string" - } - ], - "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", - "x-links": [ - "https://json-schema.org/draft/2020-12/json-schema-core#name-json-schema-documents" - ], - "type": [ "object", "boolean" ] -} diff --git a/schemas/2020-12/misc/single-line-text.json b/schemas/2020-12/misc/single-line-text.json deleted file mode 100644 index 99267427..00000000 --- a/schemas/2020-12/misc/single-line-text.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "Single-line Text", - "description": "A string representing a single line of clean text without leading or trailing whitespace, excessive internal spacing, non-printable characters, newlines, tabs, trailing periods, or other punctuation issues", - "examples": [ - "This is a simple text", - "Multiple sentences work fine", - "Numbers and symbols: 123 $%&", - "Unicode characters are allowed: café, 日本語" - ], - "x-license": "https://github.com/sourcemeta/std/blob/main/LICENSE", - "x-links": [ "https://en.wikipedia.org/wiki/String_(computer_science)" ], - "type": "string", - "pattern": "^(?!.*\\.$)(?!.*(?