Skip to content

Commit 87841eb

Browse files
committed
[WIP] Publish the standard library to NPM
Signed-off-by: Juan Cruz Viotti <[email protected]>
1 parent 16b04cd commit 87841eb

File tree

7 files changed

+194
-0
lines changed

7 files changed

+194
-0
lines changed

.npmignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
*
2+
!LICENSE
3+
!README.markdown
4+
!schemas
5+
!schemas/**
6+
!npm
7+
!npm/**
8+
npm/**/*.test.js
9+
npm/**/*.test.mjs

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ UNZIP ?= unzip
99
GZIP ?= gzip
1010
MKDIRP ?= mkdir -p
1111
RMRF ?= rm -rf
12+
NODE ?= node
13+
NPM ?= npm
1214

1315
include generated.mk
1416

@@ -37,6 +39,8 @@ lint: common
3739
.PHONY: test
3840
test:
3941
$(JSONSCHEMA) test ./test
42+
$(NODE) npm/cjs.test.js
43+
$(NODE) npm/esm.test.mjs
4044

4145
# TODO: Add a `jsonschema pkg` command instead
4246
.PHONY: dist
@@ -51,3 +55,6 @@ dist:
5155
$(TAR) -rf $@/sourcemeta-std-v$(VERSION).tar LICENSE
5256
$(GZIP) $@/sourcemeta-std-v$(VERSION).tar
5357
$(TAR) -tzf $@/sourcemeta-std-v$(VERSION).tar.gz
58+
$(MKDIRP) $@/npm
59+
$(NPM) version --no-git-tag-version --allow-same-version "$(VERSION)"
60+
$(NPM) pack --pack-destination $@/npm

npm/cjs.test.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const test = require('node:test');
2+
const assert = require('node:assert');
3+
const getSchema = require('..');
4+
5+
test('loads a valid schema', () => {
6+
const schema = getSchema('2020-12/misc/schema-like');
7+
assert.strictEqual(typeof schema, 'object');
8+
assert.strictEqual(schema.$schema, 'https://json-schema.org/draft/2020-12/schema');
9+
assert.strictEqual(schema.title, 'JSON Schema Document');
10+
});
11+
12+
test('returns null for non-existent schema', () => {
13+
const schema = getSchema('nonexistent/schema/path');
14+
assert.strictEqual(schema, null);
15+
});
16+
17+
test('returns null for invalid input types', () => {
18+
assert.strictEqual(getSchema(null), null);
19+
assert.strictEqual(getSchema(undefined), null);
20+
assert.strictEqual(getSchema(123), null);
21+
assert.strictEqual(getSchema({}), null);
22+
});
23+
24+
test('blocks directory traversal attempts', () => {
25+
const schema = getSchema('../package');
26+
assert.strictEqual(schema, null);
27+
});
28+
29+
test('blocks directory traversal with multiple levels', () => {
30+
const schema = getSchema('../../etc/passwd');
31+
assert.strictEqual(schema, null);
32+
});
33+
34+
test('loads schema from nested path', () => {
35+
const schema = getSchema('2020-12/w3c/xmlschema/2001/hex-binary');
36+
assert.strictEqual(typeof schema, 'object');
37+
assert.strictEqual(schema.$schema, 'https://json-schema.org/draft/2020-12/schema');
38+
});

npm/esm.test.mjs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import test from 'node:test';
2+
import assert from 'node:assert';
3+
import getSchema from '@sourcemeta/std';
4+
5+
test('loads a valid schema', () => {
6+
const schema = getSchema('2020-12/misc/schema-like');
7+
assert.strictEqual(typeof schema, 'object');
8+
assert.strictEqual(schema.$schema, 'https://json-schema.org/draft/2020-12/schema');
9+
assert.strictEqual(schema.title, 'JSON Schema Document');
10+
});
11+
12+
test('returns null for non-existent schema', () => {
13+
const schema = getSchema('nonexistent/schema/path');
14+
assert.strictEqual(schema, null);
15+
});
16+
17+
test('returns null for invalid input types', () => {
18+
assert.strictEqual(getSchema(null), null);
19+
assert.strictEqual(getSchema(undefined), null);
20+
assert.strictEqual(getSchema(123), null);
21+
assert.strictEqual(getSchema({}), null);
22+
});
23+
24+
test('blocks directory traversal attempts', () => {
25+
const schema = getSchema('../package');
26+
assert.strictEqual(schema, null);
27+
});
28+
29+
test('blocks directory traversal with multiple levels', () => {
30+
const schema = getSchema('../../etc/passwd');
31+
assert.strictEqual(schema, null);
32+
});
33+
34+
test('loads schema from nested path', () => {
35+
const schema = getSchema('2020-12/w3c/xmlschema/2001/hex-binary');
36+
assert.strictEqual(typeof schema, 'object');
37+
assert.strictEqual(schema.$schema, 'https://json-schema.org/draft/2020-12/schema');
38+
});

npm/main.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
4+
function getSchema(schemaPath) {
5+
if (!schemaPath || typeof schemaPath !== 'string') {
6+
return null;
7+
}
8+
9+
if (schemaPath.includes('..')) {
10+
return null;
11+
}
12+
13+
const absolutePath = path.join(__dirname, '..', 'schemas', `${schemaPath}.json`);
14+
15+
try {
16+
const content = fs.readFileSync(absolutePath, 'utf8');
17+
return JSON.parse(content);
18+
} catch (error) {
19+
return null;
20+
}
21+
}
22+
23+
module.exports = getSchema;

npm/main.mjs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
import { fileURLToPath } from 'url';
4+
5+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
6+
7+
function getSchema(schemaPath) {
8+
if (!schemaPath || typeof schemaPath !== 'string') {
9+
return null;
10+
}
11+
12+
if (schemaPath.includes('..')) {
13+
return null;
14+
}
15+
16+
const absolutePath = path.join(__dirname, '..', 'schemas', `${schemaPath}.json`);
17+
18+
try {
19+
const content = fs.readFileSync(absolutePath, 'utf8');
20+
return JSON.parse(content);
21+
} catch (error) {
22+
return null;
23+
}
24+
}
25+
26+
export default getSchema;

package.json

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"name": "@sourcemeta/std",
3+
"version": "0.3.0",
4+
"description": "A growing collection of hand-crafted high-quality schemas, From RFC-compliant Email Address schemas to ISO-compliant Currency Codes",
5+
"main": "npm/main.js",
6+
"module": "npm/main.mjs",
7+
"exports": {
8+
".": {
9+
"import": "./npm/main.mjs",
10+
"require": "./npm/main.js"
11+
}
12+
},
13+
"license": "UNLICENSED",
14+
"homepage": "https://github.com/sourcemeta/std",
15+
"author": {
16+
"email": "[email protected]",
17+
"name": "Sourcemeta",
18+
"url": "https://www.sourcemeta.com"
19+
},
20+
"funding": "https://github.com/sponsors/sourcemeta",
21+
"keywords": [
22+
"jsonschema",
23+
"json",
24+
"schema",
25+
"json-schema",
26+
"cli",
27+
"$ref",
28+
"dereference",
29+
"reference",
30+
"resolve",
31+
"json-pointer",
32+
"validator",
33+
"validation",
34+
"bundle",
35+
"json-schema-validator",
36+
"json-schema-validation",
37+
"lint",
38+
"format",
39+
"draft",
40+
"library"
41+
],
42+
"bugs": {
43+
"url": "https://github.com/sourcemeta/std/issues"
44+
},
45+
"repository": {
46+
"type": "git",
47+
"url": "git+https://github.com/sourcemeta/std.git"
48+
},
49+
"publishConfig": {
50+
"provenance": true,
51+
"access": "public"
52+
}
53+
}

0 commit comments

Comments
 (0)