siteplane 0.1.60 → 0.1.61
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 +6 -3
- package/dist/bin/siteplane.js +45 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -81,7 +81,10 @@ siteplane setup deploy --wait
|
|
|
81
81
|
|
|
82
82
|
Commit only intended source before deploy. The CLI securely transfers its Production environment, adopts or
|
|
83
83
|
starts one matching deployment and verifies the actual build and signed runtime. Unchanged resume creates no
|
|
84
|
-
new deployment.
|
|
84
|
+
new deployment. If the linked project has multiple verified, non-redirecting Production domains, select the
|
|
85
|
+
canonical one on the first run with `siteplane setup deploy --wait --production-origin <https-origin>`. The CLI
|
|
86
|
+
rejects foreign, redirect, branch and unverified domains, stores the binding and reuses it on resume. A saved
|
|
87
|
+
15-minute provider deadline and operation identity prevent blind retries after response
|
|
85
88
|
loss. If that deadline expires after the deploy was requested, rerun the same command: each invocation gets a
|
|
86
89
|
bounded 120-second readback of that same operation. A ready result is adopted; a still-running or unreachable
|
|
87
90
|
provider remains resumable and never authorizes a second deploy. Uploads use committed source in a temporary
|
|
@@ -102,8 +105,8 @@ Before starting, add `.siteplane/credentials.json` to the repository’s `.gitig
|
|
|
102
105
|
unprotected credentials before any provisioning request.
|
|
103
106
|
|
|
104
107
|
```bash
|
|
105
|
-
npx -y siteplane@0.1.
|
|
106
|
-
npx -y siteplane@0.1.
|
|
108
|
+
npx -y siteplane@0.1.61 setup start --modules editing --instructions-file instructions.txt
|
|
109
|
+
npx -y siteplane@0.1.61 setup context
|
|
107
110
|
```
|
|
108
111
|
|
|
109
112
|
Start performs read-only preflight and saves the installation key and original request privately before the
|
package/dist/bin/siteplane.js
CHANGED
|
@@ -5605,7 +5605,7 @@ ${task.goal}
|
|
|
5605
5605
|
|
|
5606
5606
|
${task.discovery.rules.map((rule) => `- ${rule}`).join("\n")}
|
|
5607
5607
|
|
|
5608
|
-
Run setup context for the current user instructions and authorized modules. Keep the user instructions distinct from your selection summary. Use setup deploy --wait for environment transfer and deployment; never read or print credential values. If a requested deploy passes its provider deadline, rerun the same command for a bounded readback of that operation; do not start a replacement while its outcome is unresolved. For image fields, withSiteplane adds only the exact Siteplane asset route and website /siteplane-assets/ pattern while preserving existing sources, loaders, and redirect policy. This grants no hosting permission. If the website uses a global or component image loader, keep it and verify Siteplane image delivery explicitly. Inspect CSP written by middleware/proxy/meta tags before deployment.
|
|
5608
|
+
Run setup context for the current user instructions and authorized modules. Keep the user instructions distinct from your selection summary. Use setup deploy --wait for environment transfer and deployment; never read or print credential values. If the linked provider project has multiple eligible Production domains, choose its canonical verified non-redirecting origin with --production-origin <https-origin>; before an origin-dependent local build use that exact value as SITEPLANE_SITE_ORIGIN, then pass the same origin to setup deploy. Resume reuses the stored choice. If a requested deploy passes its provider deadline, rerun the same command for a bounded readback of that operation; do not start a replacement while its outcome is unresolved. For image fields, withSiteplane adds only the exact Siteplane asset route and website /siteplane-assets/ pattern while preserving existing sources, loaders, and redirect policy. This grants no hosting permission. If the website uses a global or component image loader, keep it and verify Siteplane image delivery explicitly. Inspect CSP written by middleware/proxy/meta tags before deployment. Never use a wildcard, private host or different origin for local builds.
|
|
5609
5609
|
`);
|
|
5610
5610
|
for (const [path, content] of files) {
|
|
5611
5611
|
if (path === layoutPath || path === nextPath || path === guidePath)
|
|
@@ -5902,6 +5902,17 @@ var digest = (value) => `sha256:${createHash4("sha256").update(stableJsonStringi
|
|
|
5902
5902
|
function fail2(code, message) {
|
|
5903
5903
|
throw new SetupFailure(code, message);
|
|
5904
5904
|
}
|
|
5905
|
+
function normalizeProductionOrigin(value) {
|
|
5906
|
+
let url;
|
|
5907
|
+
try {
|
|
5908
|
+
url = new URL(value);
|
|
5909
|
+
} catch {
|
|
5910
|
+
fail2("production_origin_invalid", "Choose an absolute public HTTPS origin without a path, query, fragment or credentials.");
|
|
5911
|
+
}
|
|
5912
|
+
if (url.protocol !== "https:" || url.username || url.password || url.pathname !== "/" || url.search || url.hash)
|
|
5913
|
+
fail2("production_origin_invalid", "Choose an absolute public HTTPS origin without a path, query, fragment or credentials.");
|
|
5914
|
+
return url.origin;
|
|
5915
|
+
}
|
|
5905
5916
|
var defaults = {
|
|
5906
5917
|
preflight: setupPreflightCommand,
|
|
5907
5918
|
context: siteSetupContextCommand,
|
|
@@ -5951,16 +5962,8 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5951
5962
|
...record ? { deploymentId: record.deploymentId, deadline: record.deadline } : {}
|
|
5952
5963
|
};
|
|
5953
5964
|
const { local, provider } = preflight;
|
|
5954
|
-
if (
|
|
5955
|
-
fail2("
|
|
5956
|
-
const revision = local.git.revision;
|
|
5957
|
-
if (!/^[0-9a-f]{40}$/u.test(revision))
|
|
5958
|
-
fail2("invalid_git_revision", "A full committed Git revision is required.");
|
|
5959
|
-
try {
|
|
5960
|
-
await assertExactSetupPackages(local.projectDirectory, config.packages);
|
|
5961
|
-
} catch {
|
|
5962
|
-
fail2("siteplane_package_pin_conflict", "Install the exact Siteplane package versions from the current task and commit their canonical lockfile.");
|
|
5963
|
-
}
|
|
5965
|
+
if (record && (record.projectId !== provider.projectId || record.teamId !== provider.teamId))
|
|
5966
|
+
fail2("deployment_target_conflict", "This setup already belongs to a different provider project/team. Restore its original local link.");
|
|
5964
5967
|
const recordedOperationDeadline = record && !["verified", "deployed", "failed"].includes(record.phase) ? Date.parse(record.deadline) : null;
|
|
5965
5968
|
const isExpiredDeployReadback = record?.phase === "deploy_requested" && recordedOperationDeadline !== null && recordedOperationDeadline <= deps.now();
|
|
5966
5969
|
let operationDeadline = isExpiredDeployReadback ? deps.now() + PROVIDER_RESUME_READBACK_TIMEOUT_MS : recordedOperationDeadline ?? deps.now() + PROVIDER_OPERATION_TIMEOUT_MS;
|
|
@@ -5971,14 +5974,9 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5971
5974
|
fail2("provider_deadline_exceeded", deadlineExceededMessage);
|
|
5972
5975
|
return milliseconds;
|
|
5973
5976
|
};
|
|
5974
|
-
const
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
timeoutMs: Math.min(options.timeoutMs ?? 12e4, remaining())
|
|
5978
|
-
});
|
|
5979
|
-
remaining();
|
|
5980
|
-
return output;
|
|
5981
|
-
};
|
|
5977
|
+
const selectedOrigin = input.productionOrigin ? normalizeProductionOrigin(input.productionOrigin) : null;
|
|
5978
|
+
if (record && selectedOrigin && selectedOrigin !== record.origin)
|
|
5979
|
+
fail2("production_origin_conflict", "This setup is already bound to another Production origin. Resume with the stored origin instead of changing it silently.");
|
|
5982
5980
|
const scope = `teamId=${provider.teamId}`;
|
|
5983
5981
|
const api = async (endpoint, body, method) => {
|
|
5984
5982
|
remaining();
|
|
@@ -5994,11 +5992,32 @@ async function setupDeployCommand(input, deps = defaults) {
|
|
|
5994
5992
|
gitBranch: z40.string().nullable().optional()
|
|
5995
5993
|
}))
|
|
5996
5994
|
}).parse(await api(`/v9/projects/${provider.projectId}/domains?${scope}`)).domains.filter((domain) => domain.verified && !domain.redirect && !domain.gitBranch);
|
|
5997
|
-
const
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
5995
|
+
const eligibleOrigins = domains.map((domain) => new URL(`https://${domain.name}`).origin);
|
|
5996
|
+
const origin = record?.origin ?? selectedOrigin ?? (eligibleOrigins.length === 1 ? eligibleOrigins[0] : null);
|
|
5997
|
+
if (selectedOrigin && !eligibleOrigins.includes(selectedOrigin))
|
|
5998
|
+
fail2("production_origin_not_bound", "The selected origin must be a verified, non-redirecting Production domain of this linked provider project.");
|
|
5999
|
+
if (!origin)
|
|
6000
|
+
fail2("production_origin_ambiguous", `Choose the canonical Production origin explicitly and rerun setup deploy --wait --production-origin <origin>. Eligible origins: ${eligibleOrigins.sort().join(", ") || "none"}.`);
|
|
6001
|
+
if (!eligibleOrigins.includes(origin))
|
|
6002
|
+
fail2("production_origin_not_bound", "The stored Production origin is no longer a verified, non-redirecting Production domain of this linked provider project.");
|
|
6003
|
+
if (local.git.changes.length || !local.git.revision || !local.git.branch)
|
|
6004
|
+
fail2("uncommitted_source", "Commit only the intended setup source on a named branch before deployment. Siteplane does not stage, reset or publish unrelated local work.");
|
|
6005
|
+
const revision = local.git.revision;
|
|
6006
|
+
if (!/^[0-9a-f]{40}$/u.test(revision))
|
|
6007
|
+
fail2("invalid_git_revision", "A full committed Git revision is required.");
|
|
6008
|
+
try {
|
|
6009
|
+
await assertExactSetupPackages(local.projectDirectory, config.packages);
|
|
6010
|
+
} catch {
|
|
6011
|
+
fail2("siteplane_package_pin_conflict", "Install the exact Siteplane package versions from the current task and commit their canonical lockfile.");
|
|
6012
|
+
}
|
|
6013
|
+
const processCommand = async (binary, args, options) => {
|
|
6014
|
+
const output = await deps.process(binary, args, {
|
|
6015
|
+
...options,
|
|
6016
|
+
timeoutMs: Math.min(options.timeoutMs ?? 12e4, remaining())
|
|
6017
|
+
});
|
|
6018
|
+
remaining();
|
|
6019
|
+
return output;
|
|
6020
|
+
};
|
|
6002
6021
|
const listEnv = async () => z40.object({ envs: z40.array(envSchema) }).parse(await api(`/v10/projects/${provider.projectId}/env?${scope}`)).envs;
|
|
6003
6022
|
let env = await listEnv();
|
|
6004
6023
|
const owned = (key) => {
|
|
@@ -6642,8 +6661,10 @@ async function runSetupCommand(args, dependencies) {
|
|
|
6642
6661
|
return { exitCode: 0 };
|
|
6643
6662
|
}
|
|
6644
6663
|
if (area === "deploy") {
|
|
6664
|
+
const productionOrigin = readOption(areaArgs, "--production-origin");
|
|
6645
6665
|
const result2 = await dependencies.commands.setupDeployCommand({
|
|
6646
6666
|
projectDir,
|
|
6667
|
+
...productionOrigin ? { productionOrigin } : {},
|
|
6647
6668
|
onProgress: (progress) => dependencies.stderr(JSON.stringify({ status: "waiting", ...progress }))
|
|
6648
6669
|
});
|
|
6649
6670
|
dependencies.stdout(JSON.stringify(result2, null, 2));
|