@plasius/schema 1.0.11 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/cd.yml +114 -2
- package/CHANGELOG.md +32 -2
- package/README.md +1 -0
- package/docs/adrs/adr-0001: schema.md +4 -0
- package/docs/adrs/adr-template.md +2 -0
- package/package.json +2 -1
- package/sbom.cdx.json +66 -0
- package/vitest.config.js +8 -1
package/.github/workflows/cd.yml
CHANGED
|
@@ -6,6 +6,7 @@ on:
|
|
|
6
6
|
permissions:
|
|
7
7
|
contents: write
|
|
8
8
|
id-token: write # for npm provenance (requires Node 18+ and npm >=9)
|
|
9
|
+
attestations: write
|
|
9
10
|
|
|
10
11
|
jobs:
|
|
11
12
|
publish:
|
|
@@ -24,9 +25,114 @@ jobs:
|
|
|
24
25
|
- name: Install deps (CI)
|
|
25
26
|
run: npm ci
|
|
26
27
|
|
|
28
|
+
- name: Update CHANGELOG.md (move Unreleased to new version)
|
|
29
|
+
env:
|
|
30
|
+
VERSION: ${{ steps.pkg.outputs.version }}
|
|
31
|
+
TAG: ${{ steps.pkg.outputs.tag }}
|
|
32
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
33
|
+
verbose: true
|
|
34
|
+
run: |
|
|
35
|
+
set -euo pipefail
|
|
36
|
+
git config user.name "github-actions[bot]"
|
|
37
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
38
|
+
|
|
39
|
+
FILE="CHANGELOG.md"
|
|
40
|
+
if [ ! -f "$FILE" ]; then
|
|
41
|
+
echo "No CHANGELOG.md found; skipping changelog update."
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
DATE=$(date -u +%Y-%m-%d)
|
|
46
|
+
VERSION_LINE="## [${VERSION}] - ${DATE}"
|
|
47
|
+
|
|
48
|
+
# Identify Unreleased block boundaries
|
|
49
|
+
UNREL_START=$(grep -n '^## \[Unreleased\]' "$FILE" | cut -d: -f1 || true)
|
|
50
|
+
if [ -z "$UNREL_START" ]; then
|
|
51
|
+
echo "No '## [Unreleased]' section found; skipping changelog update."
|
|
52
|
+
exit 0
|
|
53
|
+
fi
|
|
54
|
+
NEXT_HDR=$(awk 'NR>'"$UNREL_START"' && /^## \[/{print NR; exit}' "$FILE")
|
|
55
|
+
if [ -z "$NEXT_HDR" ]; then
|
|
56
|
+
NEXT_HDR=$(wc -l < "$FILE")
|
|
57
|
+
NEXT_HDR=$((NEXT_HDR+1))
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Extract sections
|
|
61
|
+
HEADER=$(sed -n "1,${UNREL_START}p" "$FILE")
|
|
62
|
+
UNREL_CONTENT=$(sed -n "$((UNREL_START+1)),$((NEXT_HDR-1))p" "$FILE")
|
|
63
|
+
TAIL=$(sed -n "${NEXT_HDR},\$p" "$FILE")
|
|
64
|
+
|
|
65
|
+
# Prepare new Unreleased template (Keep a Changelog style) without tabs/indent issues
|
|
66
|
+
NEW_UNRELEASED=$(printf '%s\n' \
|
|
67
|
+
'' \
|
|
68
|
+
'- **Added**' \
|
|
69
|
+
' - (placeholder)' \
|
|
70
|
+
'' \
|
|
71
|
+
'- **Changed**' \
|
|
72
|
+
' - (placeholder)' \
|
|
73
|
+
'' \
|
|
74
|
+
'- **Fixed**' \
|
|
75
|
+
' - (placeholder)' \
|
|
76
|
+
'' \
|
|
77
|
+
'- **Security**' \
|
|
78
|
+
' - (placeholder)')
|
|
79
|
+
|
|
80
|
+
# Build the new CHANGELOG content
|
|
81
|
+
TMP_FILE=$(mktemp)
|
|
82
|
+
{
|
|
83
|
+
printf "%s\n" "$HEADER"
|
|
84
|
+
printf "%s\n\n" "$NEW_UNRELEASED"
|
|
85
|
+
printf "%s\n" "$VERSION_LINE"
|
|
86
|
+
# If Unreleased was empty, at least add a placeholder so the section isn't blank
|
|
87
|
+
if [ -z "$(echo "$UNREL_CONTENT" | tr -d '\n' | tr -d '[:space:]')" ]; then
|
|
88
|
+
printf "### Changed\n- (no notable changes)\n\n"
|
|
89
|
+
else
|
|
90
|
+
printf "%s\n" "$UNREL_CONTENT"
|
|
91
|
+
# Ensure a trailing newline after the inserted section
|
|
92
|
+
printf "\n"
|
|
93
|
+
fi
|
|
94
|
+
printf "%s\n" "$TAIL"
|
|
95
|
+
} > "$TMP_FILE"
|
|
96
|
+
|
|
97
|
+
mv "$TMP_FILE" "$FILE"
|
|
98
|
+
|
|
99
|
+
# Update bottom compare links
|
|
100
|
+
# Update [Unreleased] compare to start at v${VERSION}
|
|
101
|
+
COMPARE_URL="https://github.com/${GITHUB_REPOSITORY}/compare/v${VERSION}...HEAD"
|
|
102
|
+
awk -v repl="[Unreleased]: ${COMPARE_URL}" 'BEGIN{OFS=FS} { if ($0 ~ /^\[Unreleased\]: /) { print repl } else { print } }' "$FILE" > "$FILE.tmp"
|
|
103
|
+
mv "$FILE.tmp" "$FILE"
|
|
104
|
+
|
|
105
|
+
# Append a link for the new version if not present
|
|
106
|
+
if ! grep -q "^\[${VERSION}\]:" "$FILE"; then
|
|
107
|
+
echo "[${VERSION}]: https://github.com/${GITHUB_REPOSITORY}/releases/tag/v${VERSION}" >> "$FILE"
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
git add "$FILE"
|
|
111
|
+
git commit -m "docs(changelog): release v${VERSION}"
|
|
112
|
+
git push
|
|
113
|
+
|
|
114
|
+
- name: Test (coverage)
|
|
115
|
+
run: npm run test -- --coverage
|
|
116
|
+
|
|
117
|
+
- name: Upload coverage to Codecov
|
|
118
|
+
uses: codecov/codecov-action@v4
|
|
119
|
+
with:
|
|
120
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
121
|
+
files: ./coverage/lcov.info
|
|
122
|
+
flags: unittests
|
|
123
|
+
fail_ci_if_error: true
|
|
124
|
+
|
|
27
125
|
- name: Build
|
|
28
126
|
run: npm run build --if-present
|
|
29
127
|
|
|
128
|
+
- name: Generate SBOM (CycloneDX)
|
|
129
|
+
run: npm sbom --sbom-format=cyclonedx --sbom-type=library --omit dev > sbom.cdx.json
|
|
130
|
+
|
|
131
|
+
- name: Attest SBOM (GitHub Artifact Attestations)
|
|
132
|
+
uses: actions/attest-build-provenance@v3
|
|
133
|
+
with:
|
|
134
|
+
subject-path: sbom.cdx.json
|
|
135
|
+
|
|
30
136
|
- name: Bump version & decide publish flags
|
|
31
137
|
id: pkg
|
|
32
138
|
env:
|
|
@@ -38,7 +144,7 @@ jobs:
|
|
|
38
144
|
NEW_VER=$(npm version patch -m "chore: release v%s [skip ci]")
|
|
39
145
|
echo "New version: $NEW_VER"
|
|
40
146
|
git push --follow-tags
|
|
41
|
-
|
|
147
|
+
|
|
42
148
|
# Expose tag (vX.Y.Z) and version (X.Y.Z) for later steps
|
|
43
149
|
VER_NO_V=${NEW_VER#v}
|
|
44
150
|
echo "tag=$NEW_VER" >> "$GITHUB_OUTPUT"
|
|
@@ -59,13 +165,19 @@ jobs:
|
|
|
59
165
|
set -euo pipefail
|
|
60
166
|
TAG="${{ steps.pkg.outputs.tag }}"
|
|
61
167
|
if gh release view "$TAG" >/dev/null 2>&1; then
|
|
62
|
-
echo "Release $TAG already exists;
|
|
168
|
+
echo "Release $TAG already exists; uploading SBOM asset."
|
|
63
169
|
else
|
|
64
170
|
gh release create "$TAG" \
|
|
65
171
|
--title "Release $TAG" \
|
|
66
172
|
--generate-notes \
|
|
67
173
|
--latest
|
|
68
174
|
fi
|
|
175
|
+
# Upload/overwrite the SBOM asset on the release
|
|
176
|
+
if [ -f sbom.cdx.json ]; then
|
|
177
|
+
gh release upload "$TAG" sbom.cdx.json --clobber
|
|
178
|
+
else
|
|
179
|
+
echo "No SBOM generated; skipping upload."
|
|
180
|
+
fi
|
|
69
181
|
|
|
70
182
|
- name: Publish
|
|
71
183
|
env:
|
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,34 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
- **Added**
|
|
13
|
+
- (placeholder)
|
|
14
|
+
|
|
15
|
+
- **Changed**
|
|
16
|
+
- (placeholder)
|
|
17
|
+
|
|
18
|
+
- **Fixed**
|
|
19
|
+
- (placeholder)
|
|
20
|
+
|
|
21
|
+
- **Security**
|
|
22
|
+
- (placeholder)
|
|
23
|
+
|
|
24
|
+
## [] - 2025-09-17
|
|
25
|
+
|
|
26
|
+
- **Added**
|
|
27
|
+
- chore: Code coverage added
|
|
28
|
+
|
|
29
|
+
- **Changed**
|
|
30
|
+
- (placeholder)
|
|
31
|
+
|
|
32
|
+
- **Fixed**
|
|
33
|
+
- (placeholder)
|
|
34
|
+
|
|
35
|
+
- **Security**
|
|
36
|
+
- (placeholder)
|
|
37
|
+
|
|
38
|
+
## [1.0.13] - 2025-09-16
|
|
39
|
+
|
|
12
40
|
- **Added**
|
|
13
41
|
- (placeholder) Add new validators, field helpers, or PII utilities here.
|
|
14
42
|
|
|
@@ -61,5 +89,7 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
|
|
|
61
89
|
|
|
62
90
|
---
|
|
63
91
|
|
|
64
|
-
[Unreleased]: https://github.com/Plasius-LTD/
|
|
65
|
-
[1.0.0]: https://github.com/Plasius-LTD/
|
|
92
|
+
[Unreleased]: https://github.com/Plasius-LTD/schema/compare/v...HEAD
|
|
93
|
+
[1.0.0]: https://github.com/Plasius-LTD/schema/releases/tag/v1.0.0
|
|
94
|
+
[1.0.13]: https://github.com/Plasius-LTD/schema/releases/tag/v1.0.13
|
|
95
|
+
[]: https://github.com/Plasius-LTD/schema/releases/tag/v
|
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@plasius/schema)
|
|
4
4
|
[](https://github.com/plasius/schema/actions/workflows/ci.yml)
|
|
5
|
+
[](https://codecov.io/gh/Plasius-LTD/schema)
|
|
5
6
|
[](./LICENSE)
|
|
6
7
|
[](./CODE_OF_CONDUCT.md)
|
|
7
8
|
[](./SECURITY.md)
|
|
@@ -39,3 +39,7 @@ We will build a **schema library** (`@plasius/schema`) that:
|
|
|
39
39
|
|
|
40
40
|
- **Do nothing:** Continue defining ad-hoc validation in each package. (Rejected: inconsistent and unsafe.)
|
|
41
41
|
- **Use an existing library (e.g. Zod, Yup, Joi):** These provide schema validation but lack PII auditing integration and may not align with our field-builder pattern. (Rejected for core use, though we may draw inspiration.)
|
|
42
|
+
|
|
43
|
+
## References
|
|
44
|
+
|
|
45
|
+
- [Architectural Decision Records (ADR) standard](https://adr.github.io/)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plasius/schema",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.17",
|
|
4
4
|
"description": "Entity schema definition & validation helpers for Plasius ecosystem",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"@types/node": "^24.3.1",
|
|
59
59
|
"@typescript-eslint/eslint-plugin": "^8.43.0",
|
|
60
60
|
"@typescript-eslint/parser": "^8.43.0",
|
|
61
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
61
62
|
"eslint": "^9.35.0",
|
|
62
63
|
"tsup": "^8.5.0",
|
|
63
64
|
"tsx": "^4.20.5",
|
package/sbom.cdx.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
|
3
|
+
"bomFormat": "CycloneDX",
|
|
4
|
+
"specVersion": "1.5",
|
|
5
|
+
"serialNumber": "urn:uuid:43d0373e-dc7f-4ab2-8ccd-d33f85227d3f",
|
|
6
|
+
"version": 1,
|
|
7
|
+
"metadata": {
|
|
8
|
+
"timestamp": "2025-09-17T15:25:09.276Z",
|
|
9
|
+
"lifecycles": [
|
|
10
|
+
{
|
|
11
|
+
"phase": "build"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"tools": [
|
|
15
|
+
{
|
|
16
|
+
"vendor": "npm",
|
|
17
|
+
"name": "cli",
|
|
18
|
+
"version": "10.9.3"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"component": {
|
|
22
|
+
"bom-ref": "@plasius/schema@1.0.16",
|
|
23
|
+
"type": "library",
|
|
24
|
+
"name": "schema",
|
|
25
|
+
"version": "1.0.16",
|
|
26
|
+
"scope": "required",
|
|
27
|
+
"author": "Plasius LTD",
|
|
28
|
+
"description": "Entity schema definition & validation helpers for Plasius ecosystem",
|
|
29
|
+
"purl": "pkg:npm/%40plasius/schema@1.0.16",
|
|
30
|
+
"properties": [
|
|
31
|
+
{
|
|
32
|
+
"name": "cdx:npm:package:path",
|
|
33
|
+
"value": ""
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"externalReferences": [
|
|
37
|
+
{
|
|
38
|
+
"type": "vcs",
|
|
39
|
+
"url": "git+https://github.com/Plasius-LTD/schema.git"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"type": "website",
|
|
43
|
+
"url": "https://github.com/Plasius-LTD/schema#readme"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"type": "issue-tracker",
|
|
47
|
+
"url": "https://github.com/Plasius-LTD/schema/issues"
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"licenses": [
|
|
51
|
+
{
|
|
52
|
+
"license": {
|
|
53
|
+
"id": "Apache-2.0"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"components": [],
|
|
60
|
+
"dependencies": [
|
|
61
|
+
{
|
|
62
|
+
"ref": "@plasius/schema@1.0.16",
|
|
63
|
+
"dependsOn": []
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
package/vitest.config.js
CHANGED
|
@@ -6,8 +6,15 @@ export default defineConfig({
|
|
|
6
6
|
globals: true,
|
|
7
7
|
include: ["tests/**/*.test.{ts,tsx}"],
|
|
8
8
|
coverage: {
|
|
9
|
+
provider: "v8",
|
|
9
10
|
reporter: ["text", "lcov"],
|
|
10
|
-
|
|
11
|
+
reportsDirectory: "./coverage",
|
|
12
|
+
exclude: [
|
|
13
|
+
"tests/**",
|
|
14
|
+
"dist/**",
|
|
15
|
+
"**/*.config.{js,ts}",
|
|
16
|
+
"**/.eslintrc.{js,cjs}",
|
|
17
|
+
],
|
|
11
18
|
},
|
|
12
19
|
},
|
|
13
20
|
});
|