@bardioc/create-bardioc-app 0.6.0 → 0.7.0
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/README.md +5 -1
- package/package.json +1 -1
- package/templates/_base/.claude/commands/refresh-bundle.md +2 -2
- package/templates/_base/README.md +6 -3
- package/templates/_base/scripts/audit.mjs +50 -0
- package/templates/_base/scripts/compliance-summary.mjs +42 -0
- package/templates/_base/scripts/compliance.mjs +64 -0
- package/templates/_base/scripts/stamp-manifest.mjs +10 -4
- package/templates/angular/_gitignore +6 -0
- package/templates/angular/package.json +8 -2
- package/templates/angular/src/main.ts +0 -1
- package/templates/nextjs/_gitignore +6 -0
- package/templates/nextjs/app/page.tsx +1 -7
- package/templates/nextjs/package.json +8 -2
- package/templates/preact/_gitignore +6 -0
- package/templates/preact/package.json +8 -2
- package/templates/preact/src/main.tsx +1 -7
- package/templates/solid/_gitignore +6 -0
- package/templates/solid/package.json +8 -2
- package/templates/solid/src/main.tsx +1 -7
- package/templates/svelte/_gitignore +6 -0
- package/templates/svelte/package.json +8 -2
- package/templates/svelte/src/main.ts +1 -7
- package/templates/vite/_gitignore +6 -0
- package/templates/vite/package.json +8 -2
- package/templates/vite/src/main.tsx +1 -7
- package/templates/vue/_gitignore +6 -0
- package/templates/vue/package.json +8 -2
- package/templates/vue/src/main.ts +1 -7
package/README.md
CHANGED
|
@@ -49,7 +49,11 @@ Every scaffolded app ships a lightweight versioning toolkit:
|
|
|
49
49
|
|
|
50
50
|
- **Changesets** (`.changeset/` + `changeset`/`release:*` scripts) for semver-versioning the app
|
|
51
51
|
- **`scripts/stamp-manifest.mjs`** — folds `package.json`'s version into the built `app-manifest.json`
|
|
52
|
-
|
|
52
|
+
and `manifest.yaml` (wired into `npm run build` / `npm run bundle`)
|
|
53
|
+
- **Compliance gate** (`scripts/compliance.mjs`, `audit.mjs`, `compliance-summary.mjs` + `sbom` /
|
|
54
|
+
`compliance` / `audit:security` / `compliance:all` scripts) — `npm run bundle` first writes a
|
|
55
|
+
CycloneDX SBOM, checks production licenses against an allow list and fails on high/critical audit
|
|
56
|
+
findings; the four reports land in `public/` and ship inside the zip
|
|
53
57
|
- Two Claude skills under `.claude/commands/`: **`/changeset-app`** (bump locally) and
|
|
54
58
|
**`/refresh-bundle`** (rebuild the zip and swap it into a WebOS host checkout)
|
|
55
59
|
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@ Re-bundle **this** standalone hosted app and swap the fresh zip into the WebOS h
|
|
|
12
12
|
The flow, end to end:
|
|
13
13
|
|
|
14
14
|
1. **Remove** the stale zip in this app repo (forces a clean rebundle, never copies a stale artifact).
|
|
15
|
-
2. **Bundle** via this repo's `npm run bundle` script (
|
|
15
|
+
2. **Bundle** via this repo's `npm run bundle` script (`npm run compliance:all && <build> && node scripts/stamp-manifest.mjs && zip → <app>.zip`).
|
|
16
16
|
3. **Replace** `<host>/apps/webos-host/public/_apps/<app>.zip` with the freshly built one.
|
|
17
17
|
|
|
18
18
|
## Arguments
|
|
@@ -69,7 +69,7 @@ Then verify the artifact was actually produced:
|
|
|
69
69
|
test -f "$REPO/$ZIP" && ls -l "$REPO/$ZIP" || { echo "Bundle did not produce $ZIP"; exit 1; }
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
If `npm run bundle` fails (build errors), **stop and report the real failure** — do not copy anything.
|
|
72
|
+
If `npm run bundle` fails (compliance gate or build errors), **stop and report the real failure** — do not copy anything.
|
|
73
73
|
You may fix an obvious issue and retry once; on a second failure, report it truthfully and ask the
|
|
74
74
|
user how to proceed.
|
|
75
75
|
|
|
@@ -69,11 +69,14 @@ resolves from Nexus. No overlay or CI-only workspace file needed.
|
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
npm run build # type-check + build (+ stamp the manifest version) → output dir
|
|
72
|
-
npm run bundle # build + zip → {{APP_NAME}}.zip
|
|
72
|
+
npm run bundle # compliance gate + build + zip → {{APP_NAME}}.zip
|
|
73
|
+
npm run compliance:all # SBOM + license check + vulnerability audit → public/*.json
|
|
73
74
|
```
|
|
74
75
|
|
|
75
|
-
`scripts/stamp-manifest.mjs` folds `package.json`'s `version` into the built `app-manifest.json`
|
|
76
|
-
|
|
76
|
+
`scripts/stamp-manifest.mjs` folds `package.json`'s `version` into the built `app-manifest.json` and
|
|
77
|
+
`manifest.yaml`. `npm run bundle` starts with the compliance gate: it stops on a production dependency
|
|
78
|
+
whose license is not on the allow list in `scripts/compliance.mjs`, or on a high or critical audit
|
|
79
|
+
finding, and ships the SBOM and the reports inside the zip. `{{APP_NAME}}.zip` is the deliverable uploaded
|
|
77
80
|
to the Bardioc host as a hosted app. To swap a fresh build into a local WebOS host checkout, run the
|
|
78
81
|
**`/refresh-bundle`** skill.
|
|
79
82
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Vulnerability gate: scans production dependencies via npm audit, fails on high/critical findings.
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
|
|
6
|
+
const FAIL_SEVERITIES = ['high', 'critical'];
|
|
7
|
+
|
|
8
|
+
const outDir = resolve(process.argv[2] ?? 'public');
|
|
9
|
+
mkdirSync(outDir, { recursive: true });
|
|
10
|
+
|
|
11
|
+
// npm audit exits non-zero when vulnerabilities exist, so exit code is not an error signal here.
|
|
12
|
+
const res = spawnSync('npm', ['audit', '--omit=dev', '--json'], {
|
|
13
|
+
encoding: 'utf8',
|
|
14
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
15
|
+
});
|
|
16
|
+
if (!res.stdout) {
|
|
17
|
+
console.error('npm audit produced no output:', res.stderr);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
const audit = JSON.parse(res.stdout);
|
|
21
|
+
const counts = audit.metadata?.vulnerabilities ?? {};
|
|
22
|
+
|
|
23
|
+
const findings = Object.values(audit.vulnerabilities ?? {}).map(v => ({
|
|
24
|
+
name: v.name,
|
|
25
|
+
severity: v.severity,
|
|
26
|
+
range: v.range,
|
|
27
|
+
fixAvailable: v.fixAvailable,
|
|
28
|
+
advisories: (v.via ?? [])
|
|
29
|
+
.filter(x => typeof x === 'object')
|
|
30
|
+
.map(x => ({ title: x.title, url: x.url, severity: x.severity, cwe: x.cwe, cvss: x.cvss })),
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
const blocking = findings.filter(f => FAIL_SEVERITIES.includes(f.severity));
|
|
34
|
+
const report = {
|
|
35
|
+
generatedAt: new Date().toISOString(),
|
|
36
|
+
tool: 'npm audit (production dependencies)',
|
|
37
|
+
failOn: FAIL_SEVERITIES,
|
|
38
|
+
counts,
|
|
39
|
+
passed: blocking.length === 0,
|
|
40
|
+
findings,
|
|
41
|
+
};
|
|
42
|
+
writeFileSync(resolve(outDir, 'security-audit.json'), JSON.stringify(report, null, 2));
|
|
43
|
+
|
|
44
|
+
console.log('Vulnerability scan:', JSON.stringify(counts));
|
|
45
|
+
if (blocking.length > 0) {
|
|
46
|
+
console.error('Blocking vulnerabilities:');
|
|
47
|
+
for (const f of blocking) console.error(` ${f.name} (${f.severity}) ${f.range}`);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
console.log('No high/critical vulnerabilities.');
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Aggregates SBOM, license, and vulnerability reports into one verdict a reviewer or CI can read.
|
|
2
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
|
|
5
|
+
const dir = resolve(process.argv[2] ?? 'public');
|
|
6
|
+
const readJson = f => JSON.parse(readFileSync(resolve(dir, f), 'utf8'));
|
|
7
|
+
|
|
8
|
+
const pkg = JSON.parse(readFileSync('package.json', 'utf8'));
|
|
9
|
+
const sbom = readJson('sbom.cdx.json');
|
|
10
|
+
const licenses = readJson('license-compliance.json');
|
|
11
|
+
const audit = readJson('security-audit.json');
|
|
12
|
+
|
|
13
|
+
const summary = {
|
|
14
|
+
app: { name: pkg.name, version: pkg.version },
|
|
15
|
+
generatedAt: new Date().toISOString(),
|
|
16
|
+
checks: {
|
|
17
|
+
sbom: {
|
|
18
|
+
passed: true,
|
|
19
|
+
format: `CycloneDX ${sbom.specVersion}`,
|
|
20
|
+
components: sbom.components?.length ?? 0,
|
|
21
|
+
report: 'sbom.cdx.json',
|
|
22
|
+
},
|
|
23
|
+
licenses: {
|
|
24
|
+
passed: licenses.violations.length === 0,
|
|
25
|
+
packagesScanned: licenses.totalPackages,
|
|
26
|
+
violations: licenses.violations.length,
|
|
27
|
+
allowedLicenses: licenses.allowedLicenses,
|
|
28
|
+
report: 'license-compliance.json',
|
|
29
|
+
},
|
|
30
|
+
vulnerabilities: {
|
|
31
|
+
passed: audit.passed,
|
|
32
|
+
counts: audit.counts,
|
|
33
|
+
failOn: audit.failOn,
|
|
34
|
+
report: 'security-audit.json',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
summary.passed = Object.values(summary.checks).every(c => c.passed);
|
|
39
|
+
|
|
40
|
+
writeFileSync(resolve(dir, 'compliance-summary.json'), JSON.stringify(summary, null, 2));
|
|
41
|
+
console.log(`Compliance summary: ${summary.passed ? 'PASSED' : 'FAILED'}`);
|
|
42
|
+
if (!summary.passed) process.exit(1);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// License compliance gate: fails the build when a production dependency uses a non-allowed license.
|
|
2
|
+
import { execFileSync } from 'node:child_process';
|
|
3
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
|
|
6
|
+
const ALLOWED_LICENSES = [
|
|
7
|
+
'MIT',
|
|
8
|
+
'ISC',
|
|
9
|
+
'Apache-2.0',
|
|
10
|
+
'BSD-2-Clause',
|
|
11
|
+
'BSD-3-Clause',
|
|
12
|
+
'0BSD',
|
|
13
|
+
'CC0-1.0',
|
|
14
|
+
'Unlicense',
|
|
15
|
+
// Permissive OSI license (PSF); argparse, a js-yaml dependency, ships under it.
|
|
16
|
+
'Python-2.0',
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
const outDir = resolve(process.argv[2] ?? 'dist/reports');
|
|
20
|
+
mkdirSync(outDir, { recursive: true });
|
|
21
|
+
|
|
22
|
+
const raw = execFileSync(
|
|
23
|
+
'npx',
|
|
24
|
+
['license-checker-rseidelsohn', '--production', '--json', '--excludePrivatePackages'],
|
|
25
|
+
{ encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 }
|
|
26
|
+
);
|
|
27
|
+
const packages = JSON.parse(raw);
|
|
28
|
+
|
|
29
|
+
// SPDX expressions: "A AND B" needs every part allowed, "A OR B" lets us pick an
|
|
30
|
+
// allowed alternative (e.g. dompurify's "MPL-2.0 OR Apache-2.0").
|
|
31
|
+
const isAllowed = licenses => {
|
|
32
|
+
const expr = String(licenses).replaceAll(/[()]/g, '');
|
|
33
|
+
const conjuncts = expr.split(/\s+AND\s+/);
|
|
34
|
+
return conjuncts.every(part =>
|
|
35
|
+
part.split(/\s+OR\s+/).some(l => ALLOWED_LICENSES.includes(l.trim()))
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const violations = [];
|
|
40
|
+
const summary = {};
|
|
41
|
+
for (const [name, info] of Object.entries(packages)) {
|
|
42
|
+
const license = String(info.licenses);
|
|
43
|
+
summary[license] = (summary[license] ?? 0) + 1;
|
|
44
|
+
if (!isAllowed(license)) violations.push({ package: name, license, repository: info.repository });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const report = {
|
|
48
|
+
generatedAt: new Date().toISOString(),
|
|
49
|
+
allowedLicenses: ALLOWED_LICENSES,
|
|
50
|
+
totalPackages: Object.keys(packages).length,
|
|
51
|
+
licenseSummary: summary,
|
|
52
|
+
violations,
|
|
53
|
+
packages,
|
|
54
|
+
};
|
|
55
|
+
writeFileSync(resolve(outDir, 'license-compliance.json'), JSON.stringify(report, null, 2));
|
|
56
|
+
|
|
57
|
+
console.log(`License compliance: ${report.totalPackages} packages scanned`);
|
|
58
|
+
console.table(summary);
|
|
59
|
+
if (violations.length > 0) {
|
|
60
|
+
console.error('License violations found:');
|
|
61
|
+
for (const v of violations) console.error(` ${v.package}: ${v.license}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
console.log('No license violations.');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Folds package.json's version into the built app-manifest.json
|
|
2
|
-
//
|
|
1
|
+
// Folds package.json's version into the built app-manifest.json and manifest.yaml. Output dir comes
|
|
2
|
+
// from argv (defaults to dist). Idempotent.
|
|
3
3
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
4
4
|
|
|
5
5
|
const root = new URL('..', import.meta.url);
|
|
@@ -8,10 +8,16 @@ const { version } = JSON.parse(readFileSync(new URL('package.json', root), 'utf8
|
|
|
8
8
|
|
|
9
9
|
const url = new URL(`${outDir}/app-manifest.json`, root);
|
|
10
10
|
const manifest = JSON.parse(readFileSync(url, 'utf8'));
|
|
11
|
-
const base = (manifest.description ?? '').replace(/\s*\(v[^)]*\)\s*$/, '').trim();
|
|
12
11
|
|
|
13
12
|
manifest.version = version;
|
|
14
|
-
|
|
13
|
+
// The version lives in its own field; a "(vX.Y.Z)" suffix left by an older stamp is dropped.
|
|
14
|
+
if (manifest.description) {
|
|
15
|
+
manifest.description = manifest.description.replace(/\s*\(v[^)]*\)\s*$/, '').trim();
|
|
16
|
+
}
|
|
15
17
|
|
|
16
18
|
writeFileSync(url, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
19
|
+
|
|
20
|
+
// The legacy manifest.yaml carries the same version for the store's uploader.
|
|
21
|
+
const yamlUrl = new URL(`${outDir}/manifest.yaml`, root);
|
|
22
|
+
writeFileSync(yamlUrl, `name: ${manifest.id}\nversion: ${version}\n`);
|
|
17
23
|
process.stdout.write(`[stamp-manifest] ${version} → ${outDir}/app-manifest.json\n`);
|
|
@@ -9,7 +9,11 @@
|
|
|
9
9
|
"dev": "node ./scripts/dev.mjs",
|
|
10
10
|
"prebuild": "npm run sync:runtime-env",
|
|
11
11
|
"build": "ng build && node scripts/stamp-manifest.mjs dist/{{APP_NAME}}/browser",
|
|
12
|
-
"bundle": "ng build && node scripts/stamp-manifest.mjs dist/{{APP_NAME}}/browser && cd dist/{{APP_NAME}}/browser && zip -r ../../../{{APP_NAME}}.zip .",
|
|
12
|
+
"bundle": "npm run compliance:all && ng build && node scripts/stamp-manifest.mjs dist/{{APP_NAME}}/browser && cd dist/{{APP_NAME}}/browser && zip -r ../../../{{APP_NAME}}.zip .",
|
|
13
|
+
"sbom": "cyclonedx-npm --omit dev --output-format json --output-reproducible --output-file public/sbom.cdx.json",
|
|
14
|
+
"compliance": "node scripts/compliance.mjs public",
|
|
15
|
+
"audit:security": "node scripts/audit.mjs public",
|
|
16
|
+
"compliance:all": "npm run sbom && npm run compliance && npm run audit:security && node scripts/compliance-summary.mjs public",
|
|
13
17
|
"prewatch": "npm run sync:runtime-env",
|
|
14
18
|
"watch": "ng build --watch --configuration development",
|
|
15
19
|
"precheck-types": "npm run sync:runtime-env",
|
|
@@ -28,7 +32,7 @@
|
|
|
28
32
|
"@angular/platform-browser": "^19.2.12",
|
|
29
33
|
"@angular/platform-browser-dynamic": "^19.2.12",
|
|
30
34
|
"@angular/router": "^19.2.12",
|
|
31
|
-
"@bardioc/app-sdk": "^1.0.
|
|
35
|
+
"@bardioc/app-sdk": "^1.0.1",
|
|
32
36
|
"rxjs": "~7.8.2",
|
|
33
37
|
"tslib": "^2.8.1",
|
|
34
38
|
"zone.js": "~0.15.1"
|
|
@@ -38,8 +42,10 @@
|
|
|
38
42
|
"@angular/cli": "^19.2.13",
|
|
39
43
|
"@angular/compiler-cli": "^19.2.12",
|
|
40
44
|
"@changesets/cli": "^2.31.0",
|
|
45
|
+
"@cyclonedx/cyclonedx-npm": "^6.0.1",
|
|
41
46
|
"@tailwindcss/postcss": "^4.2.4",
|
|
42
47
|
"autoprefixer": "^10.4.21",
|
|
48
|
+
"license-checker-rseidelsohn": "^5.0.1",
|
|
43
49
|
"postcss": "^8.5.4",
|
|
44
50
|
"tailwindcss": "^4.2.4",
|
|
45
51
|
"typescript": "~5.8.3"
|
|
@@ -10,8 +10,6 @@ type ResultState =
|
|
|
10
10
|
| { status: 'success'; request: string; data: unknown }
|
|
11
11
|
| { status: 'error'; request: string; message: string };
|
|
12
12
|
|
|
13
|
-
const APP_NAME = process.env.NEXT_PUBLIC_APP_NAME?.trim();
|
|
14
|
-
|
|
15
13
|
// The port the app falls back to when it is not being served over HTTP (LOCALHOST_PORT moves it).
|
|
16
14
|
const DEFAULT_PORT = Number('{{PORT}}');
|
|
17
15
|
|
|
@@ -141,16 +139,12 @@ function PreviewShell() {
|
|
|
141
139
|
export default function Page() {
|
|
142
140
|
const useSdkProvider = isInsideIframe() || isDevStandalone();
|
|
143
141
|
|
|
144
|
-
if (!APP_NAME) {
|
|
145
|
-
throw new Error('Missing NEXT_PUBLIC_APP_NAME for runtime');
|
|
146
|
-
}
|
|
147
|
-
|
|
148
142
|
useEffect(() => {
|
|
149
143
|
if (isDevStandalone()) {
|
|
150
144
|
// scripts/dev.mjs runs the dev-auth proxy on the app port + 100, so read the port the page
|
|
151
145
|
// is actually served on rather than the one baked in at scaffold time.
|
|
152
146
|
const appPort = Number(window.location.port) || DEFAULT_PORT;
|
|
153
|
-
installDevHost({
|
|
147
|
+
installDevHost({ apiBaseUrl: `http://127.0.0.1:${appPort + 100}/rest` });
|
|
154
148
|
}
|
|
155
149
|
}, []);
|
|
156
150
|
|
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "node ./scripts/dev.mjs",
|
|
7
7
|
"build": "next build && node scripts/stamp-manifest.mjs out",
|
|
8
|
-
"bundle": "next build && node scripts/stamp-manifest.mjs out && cd out && zip -r ../{{APP_NAME}}.zip .",
|
|
8
|
+
"bundle": "npm run compliance:all && next build && node scripts/stamp-manifest.mjs out && cd out && zip -r ../{{APP_NAME}}.zip .",
|
|
9
|
+
"sbom": "cyclonedx-npm --omit dev --output-format json --output-reproducible --output-file public/sbom.cdx.json",
|
|
10
|
+
"compliance": "node scripts/compliance.mjs public",
|
|
11
|
+
"audit:security": "node scripts/audit.mjs public",
|
|
12
|
+
"compliance:all": "npm run sbom && npm run compliance && npm run audit:security && node scripts/compliance-summary.mjs public",
|
|
9
13
|
"start": "next start",
|
|
10
14
|
"check-types": "tsc --noEmit",
|
|
11
15
|
"lint": "eslint .",
|
|
@@ -17,7 +21,7 @@
|
|
|
17
21
|
"release:publish": "changeset publish"
|
|
18
22
|
},
|
|
19
23
|
"dependencies": {
|
|
20
|
-
"@bardioc/app-sdk": "^1.0.
|
|
24
|
+
"@bardioc/app-sdk": "^1.0.1",
|
|
21
25
|
"next": "^15.3.2",
|
|
22
26
|
"react": "^19.2.5",
|
|
23
27
|
"react-dom": "^19.2.5"
|
|
@@ -25,11 +29,13 @@
|
|
|
25
29
|
"devDependencies": {
|
|
26
30
|
"@bardioc/configs": "0.2.1",
|
|
27
31
|
"@changesets/cli": "^2.31.0",
|
|
32
|
+
"@cyclonedx/cyclonedx-npm": "^6.0.1",
|
|
28
33
|
"@tailwindcss/postcss": "^4.2.4",
|
|
29
34
|
"@types/node": "^22.10.0",
|
|
30
35
|
"@types/react": "^19.2.14",
|
|
31
36
|
"@types/react-dom": "^19.2.3",
|
|
32
37
|
"eslint": "^10.0.0",
|
|
38
|
+
"license-checker-rseidelsohn": "^5.0.1",
|
|
33
39
|
"prettier": "^3.6.2",
|
|
34
40
|
"tailwindcss": "^4.2.4",
|
|
35
41
|
"typescript": "^6.0.3"
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "tsc && vite build && node scripts/stamp-manifest.mjs dist",
|
|
9
|
-
"bundle": "tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
9
|
+
"bundle": "npm run compliance:all && tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
10
|
+
"sbom": "cyclonedx-npm --omit dev --output-format json --output-reproducible --output-file public/sbom.cdx.json",
|
|
11
|
+
"compliance": "node scripts/compliance.mjs public",
|
|
12
|
+
"audit:security": "node scripts/audit.mjs public",
|
|
13
|
+
"compliance:all": "npm run sbom && npm run compliance && npm run audit:security && node scripts/compliance-summary.mjs public",
|
|
10
14
|
"preview": "vite preview",
|
|
11
15
|
"check-types": "tsc --noEmit",
|
|
12
16
|
"lint": "eslint .",
|
|
@@ -18,16 +22,18 @@
|
|
|
18
22
|
"release:publish": "changeset publish"
|
|
19
23
|
},
|
|
20
24
|
"dependencies": {
|
|
21
|
-
"@bardioc/app-sdk": "^1.0.
|
|
25
|
+
"@bardioc/app-sdk": "^1.0.1",
|
|
22
26
|
"preact": "^10.26.7"
|
|
23
27
|
},
|
|
24
28
|
"devDependencies": {
|
|
25
29
|
"@bardioc/configs": "0.2.1",
|
|
26
30
|
"@changesets/cli": "^2.31.0",
|
|
31
|
+
"@cyclonedx/cyclonedx-npm": "^6.0.1",
|
|
27
32
|
"@preact/preset-vite": "^2.10.6",
|
|
28
33
|
"@tailwindcss/vite": "^4.3.0",
|
|
29
34
|
"@types/node": "^22.19.19",
|
|
30
35
|
"eslint": "^10.0.0",
|
|
36
|
+
"license-checker-rseidelsohn": "^5.0.1",
|
|
31
37
|
"preact-render-to-string": "^6.6.1",
|
|
32
38
|
"prettier": "^3.6.2",
|
|
33
39
|
"tailwindcss": "4.3.0",
|
|
@@ -4,18 +4,12 @@ import { render } from 'preact';
|
|
|
4
4
|
import { App } from './App';
|
|
5
5
|
import './index.css';
|
|
6
6
|
|
|
7
|
-
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
8
|
-
|
|
9
|
-
if (!APP_NAME) {
|
|
10
|
-
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
11
|
-
}
|
|
12
|
-
|
|
13
7
|
const insideIframe = isInsideIframe();
|
|
14
8
|
const devStandalone = isDevStandalone();
|
|
15
9
|
const useSdkProvider = insideIframe || devStandalone;
|
|
16
10
|
|
|
17
11
|
if (devStandalone) {
|
|
18
|
-
installDevHost(
|
|
12
|
+
installDevHost();
|
|
19
13
|
}
|
|
20
14
|
|
|
21
15
|
render(
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "tsc && vite build && node scripts/stamp-manifest.mjs dist",
|
|
9
|
-
"bundle": "tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
9
|
+
"bundle": "npm run compliance:all && tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
10
|
+
"sbom": "cyclonedx-npm --omit dev --output-format json --output-reproducible --output-file public/sbom.cdx.json",
|
|
11
|
+
"compliance": "node scripts/compliance.mjs public",
|
|
12
|
+
"audit:security": "node scripts/audit.mjs public",
|
|
13
|
+
"compliance:all": "npm run sbom && npm run compliance && npm run audit:security && node scripts/compliance-summary.mjs public",
|
|
10
14
|
"preview": "vite preview",
|
|
11
15
|
"check-types": "tsc --noEmit",
|
|
12
16
|
"lint": "eslint .",
|
|
@@ -18,15 +22,17 @@
|
|
|
18
22
|
"release:publish": "changeset publish"
|
|
19
23
|
},
|
|
20
24
|
"dependencies": {
|
|
21
|
-
"@bardioc/app-sdk": "^1.0.
|
|
25
|
+
"@bardioc/app-sdk": "^1.0.1",
|
|
22
26
|
"solid-js": "^1.9.7"
|
|
23
27
|
},
|
|
24
28
|
"devDependencies": {
|
|
25
29
|
"@bardioc/configs": "0.2.1",
|
|
26
30
|
"@changesets/cli": "^2.31.0",
|
|
31
|
+
"@cyclonedx/cyclonedx-npm": "^6.0.1",
|
|
27
32
|
"@tailwindcss/vite": "^4.3.0",
|
|
28
33
|
"@types/node": "^22.19.19",
|
|
29
34
|
"eslint": "^10.0.0",
|
|
35
|
+
"license-checker-rseidelsohn": "^5.0.1",
|
|
30
36
|
"prettier": "^3.6.2",
|
|
31
37
|
"tailwindcss": "4.3.0",
|
|
32
38
|
"typescript": "6.0.3",
|
|
@@ -5,18 +5,12 @@ import { App } from './App';
|
|
|
5
5
|
import { AppSdkProvider } from './bardioc-sdk';
|
|
6
6
|
import './index.css';
|
|
7
7
|
|
|
8
|
-
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
9
|
-
|
|
10
|
-
if (!APP_NAME) {
|
|
11
|
-
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
8
|
const insideIframe = isInsideIframe();
|
|
15
9
|
const devStandalone = isDevStandalone();
|
|
16
10
|
const useSdkProvider = insideIframe || devStandalone;
|
|
17
11
|
|
|
18
12
|
if (devStandalone) {
|
|
19
|
-
installDevHost(
|
|
13
|
+
installDevHost();
|
|
20
14
|
}
|
|
21
15
|
|
|
22
16
|
const root = document.getElementById('root')!;
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "svelte-check && vite build && node scripts/stamp-manifest.mjs dist",
|
|
9
|
-
"bundle": "svelte-check && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
9
|
+
"bundle": "npm run compliance:all && svelte-check && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
10
|
+
"sbom": "cyclonedx-npm --omit dev --output-format json --output-reproducible --output-file public/sbom.cdx.json",
|
|
11
|
+
"compliance": "node scripts/compliance.mjs public",
|
|
12
|
+
"audit:security": "node scripts/audit.mjs public",
|
|
13
|
+
"compliance:all": "npm run sbom && npm run compliance && npm run audit:security && node scripts/compliance-summary.mjs public",
|
|
10
14
|
"preview": "vite preview",
|
|
11
15
|
"check-types": "svelte-check",
|
|
12
16
|
"lint": "eslint .",
|
|
@@ -18,16 +22,18 @@
|
|
|
18
22
|
"release:publish": "changeset publish"
|
|
19
23
|
},
|
|
20
24
|
"dependencies": {
|
|
21
|
-
"@bardioc/app-sdk": "^1.0.
|
|
25
|
+
"@bardioc/app-sdk": "^1.0.1",
|
|
22
26
|
"svelte": "^5.33.14"
|
|
23
27
|
},
|
|
24
28
|
"devDependencies": {
|
|
25
29
|
"@bardioc/configs": "0.2.1",
|
|
26
30
|
"@changesets/cli": "^2.31.0",
|
|
31
|
+
"@cyclonedx/cyclonedx-npm": "^6.0.1",
|
|
27
32
|
"@sveltejs/vite-plugin-svelte": "^7.2.0",
|
|
28
33
|
"@tailwindcss/vite": "^4.3.0",
|
|
29
34
|
"@types/node": "^22.19.19",
|
|
30
35
|
"eslint": "^10.0.0",
|
|
36
|
+
"license-checker-rseidelsohn": "^5.0.1",
|
|
31
37
|
"prettier": "^3.6.2",
|
|
32
38
|
"svelte-check": "^4.2.1",
|
|
33
39
|
"tailwindcss": "4.3.0",
|
|
@@ -4,18 +4,12 @@ import { mount } from 'svelte';
|
|
|
4
4
|
import App from './App.svelte';
|
|
5
5
|
import './index.css';
|
|
6
6
|
|
|
7
|
-
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
8
|
-
|
|
9
|
-
if (!APP_NAME) {
|
|
10
|
-
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
11
|
-
}
|
|
12
|
-
|
|
13
7
|
const insideIframe = isInsideIframe();
|
|
14
8
|
const devStandalone = isDevStandalone();
|
|
15
9
|
const useSdkProvider = insideIframe || devStandalone;
|
|
16
10
|
|
|
17
11
|
if (devStandalone) {
|
|
18
|
-
installDevHost(
|
|
12
|
+
installDevHost();
|
|
19
13
|
}
|
|
20
14
|
|
|
21
15
|
const bardioc = useSdkProvider ? await connect() : null;
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "tsc && vite build && node scripts/stamp-manifest.mjs dist",
|
|
9
|
-
"bundle": "rm -f {{APP_NAME}}.zip && tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
9
|
+
"bundle": "rm -f {{APP_NAME}}.zip && npm run compliance:all && tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
10
|
+
"sbom": "cyclonedx-npm --omit dev --output-format json --output-reproducible --output-file public/sbom.cdx.json",
|
|
11
|
+
"compliance": "node scripts/compliance.mjs public",
|
|
12
|
+
"audit:security": "node scripts/audit.mjs public",
|
|
13
|
+
"compliance:all": "npm run sbom && npm run compliance && npm run audit:security && node scripts/compliance-summary.mjs public",
|
|
10
14
|
"preview": "vite preview",
|
|
11
15
|
"check-types": "tsc --noEmit",
|
|
12
16
|
"lint": "eslint .",
|
|
@@ -18,7 +22,7 @@
|
|
|
18
22
|
"release:publish": "changeset publish"
|
|
19
23
|
},
|
|
20
24
|
"dependencies": {
|
|
21
|
-
"@bardioc/app-sdk": "^1.0.
|
|
25
|
+
"@bardioc/app-sdk": "^1.0.1",
|
|
22
26
|
"@bardioc/i18n-core": "^0.1.1",
|
|
23
27
|
"@bardioc/ui": "^0.7.29",
|
|
24
28
|
"lucide-react": "^0.544.0",
|
|
@@ -28,12 +32,14 @@
|
|
|
28
32
|
"devDependencies": {
|
|
29
33
|
"@bardioc/configs": "0.2.1",
|
|
30
34
|
"@changesets/cli": "^2.31.0",
|
|
35
|
+
"@cyclonedx/cyclonedx-npm": "^6.0.1",
|
|
31
36
|
"@tailwindcss/vite": "^4.3.0",
|
|
32
37
|
"@types/node": "^22.19.19",
|
|
33
38
|
"@types/react": "^19.2.14",
|
|
34
39
|
"@types/react-dom": "^19.2.3",
|
|
35
40
|
"@vitejs/plugin-react": "5.2.0",
|
|
36
41
|
"eslint": "^10.0.0",
|
|
42
|
+
"license-checker-rseidelsohn": "^5.0.1",
|
|
37
43
|
"prettier": "^3.6.2",
|
|
38
44
|
"tailwindcss": "4.3.0",
|
|
39
45
|
"typescript": "6.0.3",
|
|
@@ -6,18 +6,12 @@ import { App } from './App';
|
|
|
6
6
|
import { AppI18nProvider } from './i18n';
|
|
7
7
|
import './index.css';
|
|
8
8
|
|
|
9
|
-
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
10
|
-
|
|
11
|
-
if (!APP_NAME) {
|
|
12
|
-
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
13
|
-
}
|
|
14
|
-
|
|
15
9
|
const insideIframe = isInsideIframe();
|
|
16
10
|
const devStandalone = isDevStandalone();
|
|
17
11
|
const useSdkProvider = insideIframe || devStandalone;
|
|
18
12
|
|
|
19
13
|
if (devStandalone) {
|
|
20
|
-
installDevHost(
|
|
14
|
+
installDevHost();
|
|
21
15
|
}
|
|
22
16
|
|
|
23
17
|
createRoot(document.getElementById('root')!).render(
|
package/templates/vue/_gitignore
CHANGED
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "vue-tsc -b && vite build && node scripts/stamp-manifest.mjs dist",
|
|
9
|
-
"bundle": "vue-tsc -b && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
9
|
+
"bundle": "npm run compliance:all && vue-tsc -b && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
10
|
+
"sbom": "cyclonedx-npm --omit dev --output-format json --output-reproducible --output-file public/sbom.cdx.json",
|
|
11
|
+
"compliance": "node scripts/compliance.mjs public",
|
|
12
|
+
"audit:security": "node scripts/audit.mjs public",
|
|
13
|
+
"compliance:all": "npm run sbom && npm run compliance && npm run audit:security && node scripts/compliance-summary.mjs public",
|
|
10
14
|
"preview": "vite preview",
|
|
11
15
|
"check-types": "vue-tsc --noEmit",
|
|
12
16
|
"lint": "eslint .",
|
|
@@ -18,16 +22,18 @@
|
|
|
18
22
|
"release:publish": "changeset publish"
|
|
19
23
|
},
|
|
20
24
|
"dependencies": {
|
|
21
|
-
"@bardioc/app-sdk": "^1.0.
|
|
25
|
+
"@bardioc/app-sdk": "^1.0.1",
|
|
22
26
|
"vue": "^3.5.16"
|
|
23
27
|
},
|
|
24
28
|
"devDependencies": {
|
|
25
29
|
"@bardioc/configs": "0.2.1",
|
|
26
30
|
"@changesets/cli": "^2.31.0",
|
|
31
|
+
"@cyclonedx/cyclonedx-npm": "^6.0.1",
|
|
27
32
|
"@tailwindcss/vite": "^4.3.0",
|
|
28
33
|
"@types/node": "^22.19.19",
|
|
29
34
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
30
35
|
"eslint": "^10.0.0",
|
|
36
|
+
"license-checker-rseidelsohn": "^5.0.1",
|
|
31
37
|
"prettier": "^3.6.2",
|
|
32
38
|
"tailwindcss": "4.3.0",
|
|
33
39
|
"typescript": "6.0.3",
|
|
@@ -5,18 +5,12 @@ import App from './App.vue';
|
|
|
5
5
|
import { BARDIOC_KEY } from './bardioc-sdk';
|
|
6
6
|
import './index.css';
|
|
7
7
|
|
|
8
|
-
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
9
|
-
|
|
10
|
-
if (!APP_NAME) {
|
|
11
|
-
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
8
|
const insideIframe = isInsideIframe();
|
|
15
9
|
const devStandalone = isDevStandalone();
|
|
16
10
|
const useSdkProvider = insideIframe || devStandalone;
|
|
17
11
|
|
|
18
12
|
if (devStandalone) {
|
|
19
|
-
installDevHost(
|
|
13
|
+
installDevHost();
|
|
20
14
|
}
|
|
21
15
|
|
|
22
16
|
const app = createApp(App);
|