Skip to content

Commit 0a82675

Browse files
committed
add validation limits basic exports and tests
1 parent 946bd0f commit 0a82675

File tree

5 files changed

+175
-53
lines changed

5 files changed

+175
-53
lines changed

pkg/package.json

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,59 @@
11
{
2-
"name": "pubky-app-specs",
3-
"description": "Pubky.app Data Model Specifications",
4-
"version": "0.4.4",
5-
"license": "MIT",
2+
"bugs": {
3+
"url": "https://github.com/pubky/pubky-app-specs/issues"
4+
},
65
"contributors": [
76
"SHAcollision",
87
"tipogi",
98
"ok300"
109
],
11-
"repository": {
12-
"type": "git",
13-
"url": "git+https://github.com/pubky/pubky-app-specs.git"
10+
"description": "Pubky.app Data Model Specifications",
11+
"devDependencies": {
12+
"mocha": "^10.2.0"
1413
},
15-
"bugs": {
16-
"url": "https://github.com/pubky/pubky-app-specs/issues"
14+
"exports": {
15+
".": {
16+
"import": "./index.js",
17+
"require": "./index.cjs",
18+
"types": "./pubky_app_specs.d.ts"
19+
},
20+
"./validationLimits": {
21+
"import": "./validationLimits.js",
22+
"require": "./validationLimits.cjs"
23+
},
24+
"./validationLimits.json": "./validationLimits.json"
1725
},
1826
"files": [
1927
"pubky_app_specs_bg.wasm",
2028
"pubky_app_specs.d.ts",
2129
"index.cjs",
2230
"index.js",
23-
"example.js"
31+
"example.js",
32+
"validationLimits.json",
33+
"validationLimits.js",
34+
"validationLimits.cjs"
2435
],
25-
"type": "module",
36+
"homepage": "https://pubky.app",
37+
"keywords": [
38+
"pubky-app",
39+
"pubky-nexus",
40+
"specs"
41+
],
42+
"license": "MIT",
2643
"main": "index.cjs",
2744
"module": "index.js",
28-
"types": "pubky_app_specs.d.ts",
29-
"exports": {
30-
".": {
31-
"types": "./pubky_app_specs.d.ts",
32-
"import": "./index.js",
33-
"require": "./index.cjs"
34-
}
35-
},
36-
"homepage": "https://pubky.app",
37-
"sideEffects": false,
38-
"devDependencies": {
39-
"mocha": "^10.2.0"
45+
"name": "pubky-app-specs",
46+
"repository": {
47+
"type": "git",
48+
"url": "git+https://github.com/pubky/pubky-app-specs.git"
4049
},
4150
"scripts": {
4251
"build": "cargo run --bin bundle_specs_npm",
4352
"example": "node example.js",
4453
"test": "mocha test.js"
4554
},
46-
"keywords": [
47-
"pubky-app",
48-
"pubky-nexus",
49-
"specs"
50-
]
55+
"sideEffects": false,
56+
"type": "module",
57+
"types": "pubky_app_specs.d.ts",
58+
"version": "0.4.4"
5159
}

pkg/test.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { PubkyAppPostKind, PubkySpecsBuilder, PubkyAppPostEmbed, postUriBuilder, bookmarkUriBuilder, followUriBuilder, userUriBuilder, getValidMimeTypes } from "./index.js";
2+
import { createRequire } from "node:module";
23
import assert from "assert";
34

5+
const require = createRequire(import.meta.url);
6+
const { validationLimits, getValidationLimits } = require("./validationLimits.cjs");
7+
const validationLimitsJson = require("./validationLimits.json");
8+
49
const OTTO = "8kkppkmiubfq4pxn6f73nqrhhhgkb5xyfprntc9si3np9ydbotto";
510
const RIO = "dzswkfy7ek3bqnoc89jxuqqfbzhjrj6mi8qthgbxxcqkdugm3rio";
611

@@ -443,4 +448,49 @@ describe("PubkySpecs Example Objects Tests", () => {
443448
assert.strictEqual(fileJson.content_type, validMimeType, "File should have valid MIME type");
444449
});
445450
});
451+
452+
describe("Validation limits exports", () => {
453+
it("should expose validationLimits from JS exports", () => {
454+
assert.ok(validationLimits, "validationLimits should be defined");
455+
assert.deepStrictEqual(
456+
validationLimits,
457+
validationLimitsJson,
458+
"validationLimits should match validationLimits.json"
459+
);
460+
assert.strictEqual(
461+
validationLimits.userNameMinLength,
462+
3,
463+
"userNameMinLength should match the Rust limits"
464+
);
465+
assert.ok(
466+
Array.isArray(validationLimits.tagInvalidChars),
467+
"tagInvalidChars should be an array"
468+
);
469+
});
470+
471+
it("getValidationLimits should return a copy that matches validationLimits", () => {
472+
const limitsCopy = getValidationLimits();
473+
474+
assert.deepStrictEqual(
475+
limitsCopy,
476+
validationLimits,
477+
"getValidationLimits should match validationLimits"
478+
);
479+
assert.notStrictEqual(
480+
limitsCopy,
481+
validationLimits,
482+
"getValidationLimits should return a new object"
483+
);
484+
});
485+
486+
it("builder.validationLimits should match the JS exports", () => {
487+
const builderLimits = JSON.parse(JSON.stringify(specsBuilder.validationLimits));
488+
489+
assert.deepStrictEqual(
490+
builderLimits,
491+
validationLimits,
492+
"builder.validationLimits should match exported validationLimits"
493+
);
494+
});
495+
});
446496
});

src/bin/bundle_specs_npm.rs

Lines changed: 89 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use serde_json::{json, Value};
12
use std::env;
23
use std::fs;
34
use std::io;
@@ -67,28 +68,94 @@ fn write_validation_limits_assets() -> io::Result<()> {
6768
let json = serde_json::to_string_pretty(&pubky_app_specs::VALIDATION_LIMITS)
6869
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
6970

70-
fs::write(pkg_dir.join("validationLimits.json"), &json)?;
71-
72-
let js = format!(
73-
"export const validationLimits = {json};\n\
74-
export const getValidationLimits = () => ({{\n\
75-
...validationLimits,\n\
76-
tagInvalidChars: [...validationLimits.tagInvalidChars],\n\
77-
postAllowedAttachmentProtocols: [...validationLimits.postAllowedAttachmentProtocols],\n\
78-
}});\n"
79-
);
80-
fs::write(pkg_dir.join("validationLimits.js"), js)?;
81-
82-
let cjs = format!(
83-
"const validationLimits = {json};\n\
84-
const getValidationLimits = () => ({{\n\
85-
...validationLimits,\n\
86-
tagInvalidChars: [...validationLimits.tagInvalidChars],\n\
87-
postAllowedAttachmentProtocols: [...validationLimits.postAllowedAttachmentProtocols],\n\
88-
}});\n\
89-
module.exports = {{ validationLimits, getValidationLimits }};\n"
90-
);
91-
fs::write(pkg_dir.join("validationLimits.cjs"), cjs)?;
71+
fs::write(pkg_dir.join("validationLimits.json"), format!("{json}\n"))?;
72+
fs::write(pkg_dir.join("validationLimits.js"), validation_limits_esm())?;
73+
fs::write(
74+
pkg_dir.join("validationLimits.cjs"),
75+
validation_limits_cjs(),
76+
)?;
9277

78+
update_package_json(&pkg_dir)?;
79+
80+
Ok(())
81+
}
82+
83+
fn validation_limits_esm() -> &'static str {
84+
"import limits from \"./validationLimits.json\" assert { type: \"json\" };\n\
85+
\n\
86+
export const validationLimits = limits;\n\
87+
export const getValidationLimits = () => JSON.parse(JSON.stringify(limits));\n\
88+
export default limits;\n"
89+
}
90+
91+
fn validation_limits_cjs() -> &'static str {
92+
"const limits = require(\"./validationLimits.json\");\n\
93+
\n\
94+
const clone = () => JSON.parse(JSON.stringify(limits));\n\
95+
\n\
96+
module.exports = {\n\
97+
validationLimits: limits,\n\
98+
getValidationLimits: clone,\n\
99+
default: limits,\n\
100+
};\n"
101+
}
102+
103+
fn update_package_json(pkg_dir: &Path) -> io::Result<()> {
104+
let package_json_path = pkg_dir.join("package.json");
105+
let package_json = fs::read_to_string(&package_json_path)?;
106+
let mut package: Value = serde_json::from_str(&package_json)
107+
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
108+
109+
ensure_files(&mut package);
110+
ensure_exports(&mut package);
111+
112+
let updated = serde_json::to_string_pretty(&package)
113+
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
114+
fs::write(package_json_path, format!("{updated}\n"))?;
93115
Ok(())
94116
}
117+
118+
fn ensure_files(package: &mut Value) {
119+
if !package.get("files").is_some() {
120+
package["files"] = Value::Array(Vec::new());
121+
}
122+
123+
let files = package
124+
.get_mut("files")
125+
.and_then(Value::as_array_mut)
126+
.expect("files array");
127+
128+
for entry in [
129+
"validationLimits.json",
130+
"validationLimits.js",
131+
"validationLimits.cjs",
132+
] {
133+
if !files.iter().any(|value| value.as_str() == Some(entry)) {
134+
files.push(Value::String(entry.to_string()));
135+
}
136+
}
137+
}
138+
139+
fn ensure_exports(package: &mut Value) {
140+
if !package.get("exports").is_some() {
141+
package["exports"] = Value::Object(serde_json::Map::new());
142+
}
143+
144+
let exports = package
145+
.get_mut("exports")
146+
.and_then(Value::as_object_mut)
147+
.expect("exports object");
148+
149+
exports
150+
.entry("./validationLimits".to_string())
151+
.or_insert_with(|| {
152+
json!({
153+
"import": "./validationLimits.js",
154+
"require": "./validationLimits.cjs"
155+
})
156+
});
157+
158+
exports
159+
.entry("./validationLimits.json".to_string())
160+
.or_insert_with(|| Value::String("./validationLimits.json".to_string()));
161+
}

src/bin/patch.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,3 @@ await Promise.all([".js", ".d.ts", "_bg.wasm"].map(suffix =>
6969
path.join(__dirname, `../../pkg/${suffix === '.js' ? "index.cjs" : (name + suffix)}`),
7070
))
7171
)
72-

src/bin/patch_async.mjs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,3 @@ const indexcjsPath = path.join(__dirname, `../../pkg/index.cjs`);
109109
const indexcjsContent = await readFile(indexcjsPath, 'utf8');
110110

111111
await writeFile(indexcjsPath, indexcjsContent, 'utf8')
112-
113-

0 commit comments

Comments
 (0)