@evcraddock/slug-cli 0.6.4 → 0.6.5

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 CHANGED
@@ -25,7 +25,7 @@ Create a standalone site with:
25
25
  slug init ./my-site --name my-site --site-title "My Site"
26
26
  ```
27
27
 
28
- Run `slug init --help` for template options. By default, `slug init` downloads the default template zip artifact. `--template-dir` remains available for local template development, `--template-url` supports alternate remote zip artifacts, and `--template` reserves the selection path for future named templates.
28
+ Run `slug init --help` for template options. By default, `slug init` downloads the latest template zip artifact and falls back to the template artifact published with the installed CLI version if the latest artifact is missing. `--template-dir` remains available for local template development, `--template-url` supports alternate remote zip artifacts, and `--template` reserves the selection path for future named templates. Explicit `--template-url` and `SLUGKIT_TEMPLATE_URL` overrides do not fall back.
29
29
 
30
30
  ## Login and configuration
31
31
 
package/dist/commands.js CHANGED
@@ -155,7 +155,7 @@ Options:
155
155
  --json Print command output as JSON.
156
156
  --help, -h Show this help.
157
157
 
158
- By default, slug init downloads the default template zip artifact. Set SLUGKIT_TEMPLATE_URL or pass --template-url to use a different zip artifact. Generated sites do not depend on the template artifact at runtime.`;
158
+ By default, slug init downloads the latest template zip artifact and falls back to the CLI-versioned artifact if latest is missing. Set SLUGKIT_TEMPLATE_URL or pass --template-url to use a different zip artifact without fallback. Generated sites do not depend on the template artifact at runtime.`;
159
159
  const SITE_INIT_NEXT_STEPS = [
160
160
  "Install dependencies",
161
161
  "Copy and edit .env",
@@ -438,17 +438,37 @@ async function resolveInitTemplateSource(context, options) {
438
438
  if (options.template !== undefined && options.template !== DEFAULT_TEMPLATE_NAME) {
439
439
  throw createInvalidUsageError(`Unsupported template: ${options.template}. Use --template-url for external template zip artifacts.`);
440
440
  }
441
- return downloadTemplateSite(context, getDefaultTemplateUrl(context));
441
+ return downloadDefaultTemplateSite(context, getDefaultTemplateResolution(context));
442
442
  }
443
- function getDefaultTemplateUrl(context) {
444
- if (context.templateAssetBaseUrl !== undefined) {
445
- return `${context.templateAssetBaseUrl.replace(/\/+$/u, "")}/slugkit-site-template.zip`;
446
- }
443
+ function getDefaultTemplateResolution(context) {
447
444
  const environmentUrl = process.env.SLUGKIT_TEMPLATE_URL?.trim();
448
445
  if (environmentUrl !== undefined && environmentUrl !== "") {
449
- return environmentUrl;
446
+ return { primaryUrl: environmentUrl };
447
+ }
448
+ const primaryUrl = context.templateAssetBaseUrl !== undefined
449
+ ? `${context.templateAssetBaseUrl.replace(/\/+$/u, "")}/slugkit-site-template.zip`
450
+ : DEFAULT_TEMPLATE_URL;
451
+ return {
452
+ primaryUrl,
453
+ fallbackUrl: getVersionedTemplateUrl(context.packageVersion),
454
+ };
455
+ }
456
+ function getVersionedTemplateUrl(packageVersion) {
457
+ const version = packageVersion.trim().replace(/^v/u, "");
458
+ return `https://forge.caradoc.com/erik/slugkit/releases/download/v${version}/slugkit-site-template-v${version}.zip`;
459
+ }
460
+ async function downloadDefaultTemplateSite(context, resolution) {
461
+ try {
462
+ return await downloadTemplateSite(context, resolution.primaryUrl);
463
+ }
464
+ catch (error) {
465
+ if (resolution.fallbackUrl === undefined ||
466
+ !(error instanceof TemplateDownloadError) ||
467
+ error.status !== 404) {
468
+ throw error;
469
+ }
470
+ return downloadTemplateSite(context, resolution.fallbackUrl);
450
471
  }
451
- return DEFAULT_TEMPLATE_URL;
452
472
  }
453
473
  async function downloadTemplateSite(context, templateUrl) {
454
474
  let parsedUrl;
@@ -464,7 +484,7 @@ async function downloadTemplateSite(context, templateUrl) {
464
484
  const fetchImpl = context.fetchImpl ?? fetch;
465
485
  const response = await fetchImpl(parsedUrl);
466
486
  if (!response.ok) {
467
- throw new CliError(`Failed to download Slugkit template from ${parsedUrl.toString()}: HTTP ${response.status}`, ExitCode.NetworkError);
487
+ throw new TemplateDownloadError(parsedUrl.toString(), response.status);
468
488
  }
469
489
  const tempDirectory = await mkdtemp(join(tmpdir(), "slug-template-"));
470
490
  const archivePath = join(tempDirectory, "template.zip");
@@ -479,6 +499,13 @@ async function downloadTemplateSite(context, templateUrl) {
479
499
  cleanup: () => rm(tempDirectory, { force: true, recursive: true }),
480
500
  };
481
501
  }
502
+ class TemplateDownloadError extends CliError {
503
+ status;
504
+ constructor(templateUrl, status) {
505
+ super(`Failed to download Slugkit template from ${templateUrl}: HTTP ${status}`, ExitCode.NetworkError);
506
+ this.status = status;
507
+ }
508
+ }
482
509
  async function findExtractedTemplateDirectory(extractDirectory) {
483
510
  if (await isTemplateSiteDirectory(extractDirectory)) {
484
511
  return extractDirectory;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evcraddock/slug-cli",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "description": "Command-line tool for Slugkit sites.",
5
5
  "private": false,
6
6
  "type": "module",