@palettelab/cli 0.3.47 → 0.3.48
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 +3 -2
- package/lib/commands/publish.js +18 -18
- package/lib/commands/test.js +44 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -678,9 +678,10 @@ Run local contract checks before publishing.
|
|
|
678
678
|
```bash
|
|
679
679
|
pltt test
|
|
680
680
|
pltt test --json
|
|
681
|
+
pltt test --publish-type preview
|
|
681
682
|
```
|
|
682
683
|
|
|
683
|
-
Checks include manifest validity, SDK/platform compatibility, semver bump detection, forbidden platform imports, frontend bundling and size limits, sandbox bridge smoke, backend dependency installation/import, route permission gates, route permission declarations, migration linting, frontend sandbox policy, and dependency policy for `package.json` / `pyproject.toml`. The default frontend and backend bundle limits are 15 MiB; set `PALETTE_MAX_FRONTEND_BUNDLE_BYTES` or `PALETTE_MAX_BACKEND_BUNDLE_BYTES` for reviewed exceptions.
|
|
684
|
+
Checks include manifest validity, SDK/platform compatibility, release semver bump detection, forbidden platform imports, frontend bundling and size limits, sandbox bridge smoke, backend dependency installation/import, route permission gates, route permission declarations, migration linting, frontend sandbox policy, and dependency policy for `package.json` / `pyproject.toml`. The semver bump check is skipped for `--publish-type preview` because hosted previews may reuse the current app version. The default frontend and backend bundle limits are 15 MiB; set `PALETTE_MAX_FRONTEND_BUNDLE_BYTES` or `PALETTE_MAX_BACKEND_BUNDLE_BYTES` for reviewed exceptions.
|
|
684
685
|
|
|
685
686
|
### `pltt package`
|
|
686
687
|
|
|
@@ -706,7 +707,7 @@ pltt publish --env staging --json
|
|
|
706
707
|
pltt publish --env staging --ttl-hours 24
|
|
707
708
|
```
|
|
708
709
|
|
|
709
|
-
Publishing first runs the same contract checks as `pltt test`. If preflight passes, it bundles frontend/backend artifacts, uploads them, creates a
|
|
710
|
+
Publishing first runs the same contract checks as `pltt test`. Preview publishes skip the release semver bump check, while release publishes still require a version newer than the last release. If preflight passes, it bundles frontend/backend artifacts, uploads them, creates a review record, and prints review/preview URLs when the platform returns them.
|
|
710
711
|
|
|
711
712
|
`--ttl-hours` sets an expiration on the preview URL. It is mainly used by `pltt dev --sandbox`, which defaults previews to 24 hours.
|
|
712
713
|
|
package/lib/commands/publish.js
CHANGED
|
@@ -138,9 +138,9 @@ function printPreflightFailure(payload, fallbackOutput) {
|
|
|
138
138
|
console.error("[pltt] Need machine-readable details? Run `pltt test --json`.")
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
function runPreflight(cwd, json) {
|
|
141
|
+
function runPreflight(cwd, json, publishType = "release") {
|
|
142
142
|
const cliBin = path.resolve(__dirname, "..", "..", "bin", "pltt.js")
|
|
143
|
-
const res = spawnSync(process.execPath, [cliBin, "test", "--json"], {
|
|
143
|
+
const res = spawnSync(process.execPath, [cliBin, "test", "--json", "--publish-type", publishType], {
|
|
144
144
|
cwd,
|
|
145
145
|
encoding: "utf8",
|
|
146
146
|
env: process.env,
|
|
@@ -296,7 +296,7 @@ async function run(argv, { cwd }) {
|
|
|
296
296
|
process.exit(1)
|
|
297
297
|
}
|
|
298
298
|
|
|
299
|
-
runPreflight(cwd, flags.json)
|
|
299
|
+
runPreflight(cwd, flags.json, publishType)
|
|
300
300
|
|
|
301
301
|
log(
|
|
302
302
|
`[pltt] publishing ${manifest.id}@${manifest.version} → ${env.name} (${env.url})`,
|
|
@@ -368,28 +368,28 @@ async function run(argv, { cwd }) {
|
|
|
368
368
|
method: "POST",
|
|
369
369
|
body: publishBody,
|
|
370
370
|
})
|
|
371
|
+
const lastPublish = {
|
|
372
|
+
id: record.id,
|
|
373
|
+
plugin_id: record.plugin_id,
|
|
374
|
+
version: record.version,
|
|
375
|
+
env: env.name,
|
|
376
|
+
url: env.url,
|
|
377
|
+
publish_type: record.publish_type || publishType,
|
|
378
|
+
preview_url: record.preview_url,
|
|
379
|
+
preview_expires_at: record.preview_expires_at,
|
|
380
|
+
published_at: new Date().toISOString(),
|
|
381
|
+
}
|
|
371
382
|
|
|
372
383
|
try {
|
|
373
384
|
const dir = path.join(cwd, ".palette")
|
|
374
385
|
fs.mkdirSync(dir, { recursive: true })
|
|
375
386
|
fs.writeFileSync(
|
|
376
387
|
path.join(dir, "last-publish.json"),
|
|
377
|
-
JSON.stringify(
|
|
378
|
-
{
|
|
379
|
-
id: record.id,
|
|
380
|
-
plugin_id: record.plugin_id,
|
|
381
|
-
version: record.version,
|
|
382
|
-
env: env.name,
|
|
383
|
-
url: env.url,
|
|
384
|
-
publish_type: record.publish_type || publishType,
|
|
385
|
-
preview_url: record.preview_url,
|
|
386
|
-
preview_expires_at: record.preview_expires_at,
|
|
387
|
-
published_at: new Date().toISOString(),
|
|
388
|
-
},
|
|
389
|
-
null,
|
|
390
|
-
2,
|
|
391
|
-
),
|
|
388
|
+
JSON.stringify(lastPublish, null, 2),
|
|
392
389
|
)
|
|
390
|
+
if ((record.publish_type || publishType) === "release") {
|
|
391
|
+
fs.writeFileSync(path.join(dir, "last-release.json"), JSON.stringify(lastPublish, null, 2))
|
|
392
|
+
}
|
|
393
393
|
} catch (err) {
|
|
394
394
|
// best-effort
|
|
395
395
|
}
|
package/lib/commands/test.js
CHANGED
|
@@ -554,17 +554,51 @@ function scanForbiddenImports(cwd, manifest, out) {
|
|
|
554
554
|
return issues.length
|
|
555
555
|
}
|
|
556
556
|
|
|
557
|
-
function
|
|
558
|
-
|
|
557
|
+
function parsePublishType(argv) {
|
|
558
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
559
|
+
const arg = argv[i]
|
|
560
|
+
if (arg === "--preview") return "preview"
|
|
561
|
+
if (arg === "--release") return "release"
|
|
562
|
+
if (arg === "--publish-type") return argv[i + 1] === "preview" ? "preview" : "release"
|
|
563
|
+
if (arg.startsWith("--publish-type=")) {
|
|
564
|
+
return arg.slice("--publish-type=".length) === "preview" ? "preview" : "release"
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return "release"
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
function readPublishState(statePath) {
|
|
559
571
|
if (!fs.existsSync(statePath)) {
|
|
560
|
-
|
|
561
|
-
return 0
|
|
572
|
+
return { state: null, invalid: false }
|
|
562
573
|
}
|
|
563
|
-
let previous
|
|
564
574
|
try {
|
|
565
|
-
|
|
575
|
+
return { state: JSON.parse(fs.readFileSync(statePath, "utf8")), invalid: false }
|
|
566
576
|
} catch (_err) {
|
|
567
|
-
|
|
577
|
+
return { state: null, invalid: true }
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
function checkSemverBump(cwd, manifest, out, publishType = "release") {
|
|
582
|
+
if (publishType === "preview") {
|
|
583
|
+
out.ok("semver bump check skipped for preview publish")
|
|
584
|
+
return 0
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
const releaseStatePath = path.join(cwd, ".palette", "last-release.json")
|
|
588
|
+
const publishStatePath = path.join(cwd, ".palette", "last-publish.json")
|
|
589
|
+
let { state: previous, invalid } = readPublishState(releaseStatePath)
|
|
590
|
+
if (!previous && !invalid) {
|
|
591
|
+
const lastPublish = readPublishState(publishStatePath)
|
|
592
|
+
invalid = lastPublish.invalid
|
|
593
|
+
if (lastPublish.state?.publish_type !== "preview") previous = lastPublish.state
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
if (!previous && !invalid) {
|
|
597
|
+
out.ok("semver bump check skipped; no previous release state")
|
|
598
|
+
return 0
|
|
599
|
+
}
|
|
600
|
+
if (invalid) {
|
|
601
|
+
out.warn("semver bump check skipped; previous publish state is invalid JSON")
|
|
568
602
|
return 0
|
|
569
603
|
}
|
|
570
604
|
const previousVersion = previous.version || previous.manifest?.version
|
|
@@ -574,7 +608,7 @@ function checkSemverBump(cwd, manifest, out) {
|
|
|
574
608
|
}
|
|
575
609
|
if (compareVersions(manifest.version, previousVersion) <= 0) {
|
|
576
610
|
return out.fail(
|
|
577
|
-
`plugin version ${manifest.version} is not newer than last
|
|
611
|
+
`plugin version ${manifest.version} is not newer than last release ${previousVersion}`,
|
|
578
612
|
"Bump manifest.version before publishing another build.",
|
|
579
613
|
{ current: manifest.version, previous: previousVersion },
|
|
580
614
|
)
|
|
@@ -683,6 +717,7 @@ function checkFrontendSecretLeaks(cwd, frontendBuffer, manifest, out) {
|
|
|
683
717
|
|
|
684
718
|
async function run(args, { cwd }) {
|
|
685
719
|
const json = args.includes("--json")
|
|
720
|
+
const publishType = parsePublishType(args)
|
|
686
721
|
let failures = 0
|
|
687
722
|
const results = []
|
|
688
723
|
const out = reporter(json, results)
|
|
@@ -709,7 +744,7 @@ async function run(args, { cwd }) {
|
|
|
709
744
|
|
|
710
745
|
failures += checkSdkCompatibility(cwd, manifest, out)
|
|
711
746
|
failures += scanForbiddenImports(cwd, manifest, out)
|
|
712
|
-
failures += checkSemverBump(cwd, manifest, out)
|
|
747
|
+
failures += checkSemverBump(cwd, manifest, out, publishType)
|
|
713
748
|
failures += checkDeclaredSecrets(cwd, manifest, out)
|
|
714
749
|
|
|
715
750
|
for (const permission of manifest.permissions || []) {
|