Socket
Socket
Sign inDemoInstall

ssg-api

Package Overview
Dependencies
Maintainers
1
Versions
76
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ssg-api - npm Package Compare versions

Comparing version 1.8.0 to 1.9.0

8

CHANGELOG.md

@@ -8,2 +8,9 @@ # Change Log

## [1.9.0] - 2024-05-20
### Changed
- `SsgConfig.outDir` is now `SsgConfig.getOutputPath(context)`
- All steps configs now extend `SsgConfig` to benefit from output path resolution.
## [1.8.0] - 2024-05-18

@@ -15,3 +22,2 @@

## [1.7.7] - 2024-05-17

@@ -18,0 +24,0 @@

2

dist/src/OutputFunc.d.ts

@@ -1,3 +0,3 @@

import { SsgContext } from './SsgContext.js';
import { SsgContext } from "./SsgContext.js";
import { SsgFile } from "./util";
export type OutputFunc = (context: SsgContext, outputFile: SsgFile) => Promise<void>;

@@ -1,3 +0,8 @@

export type SsgConfig = {
outDir: string;
};
import { SsgContext } from "./SsgContext";
export interface SsgConfig<C extends SsgContext = SsgContext> {
/**
* @param context
* @return the file where to output.
*/
getOutputPath(context: C): string;
}

@@ -0,1 +1,2 @@

/// <reference types="node" />
import { Logger } from "./Logger.js";

@@ -36,13 +37,16 @@ import { SsgFile } from "./util";

/**
* Reads a file and assign it to the context input.
* Reads a file and assign it to the context's `file`.
*
* @param fileName
* @abstract
* @param filePath
*/
getInputFrom(fileName: string): SsgFile;
read(filePath: string): SsgFile;
/**
* Reads or create (if not found) a file and assign it to the context output.
* Reads a file and assign it to the context's `file`.
*
* By default, (if the file is not found), output contents are equal to input contents.
* @abstract
* @param filePath
* @param encoding
*/
getOutputFrom(filePath: string): SsgFile;
newOutput(filePath: string, encoding?: BufferEncoding): SsgFile;
}

@@ -40,13 +40,4 @@ /// <reference types="node" />

pop(): SsgContext;
getOutputFrom(filePath: string): SsgFile;
getInputFrom(filePath: string): SsgFile;
createOutput(filePath: string, encoding: BufferEncoding): SsgFile;
/**
* Reads a file in this context.
*
* @param fileName The name of the file.
* @returns {SsgFile}
* @protected
*/
protected readFile(fileName: string): SsgFile;
read(filePath: string): SsgFile;
newOutput(filePath: string, encoding?: BufferEncoding): SsgFile;
}

@@ -79,24 +79,12 @@ import { ObjectUtil } from "./util/ObjectUtil.js";

}
getOutputFrom(filePath) {
var _a;
let outFile;
try {
outFile = this.readFile(filePath);
this.logger.debug("Read output file", outFile.name);
}
catch (e) {
if (e.code === "ENOENT") {
outFile = this.createOutput(filePath, ((_a = this._file) === null || _a === void 0 ? void 0 : _a.encoding) || "utf-8");
}
else {
throw e;
}
}
return outFile;
}
getInputFrom(filePath) {
this.file = this.readFile(filePath);
read(filePath) {
this.debug("Reading", filePath);
this.file = filePath.endsWith(".html")
? HtmlSsgFile.read(this, filePath)
: SsgFile.read(this, filePath);
return this.file;
}
createOutput(filePath, encoding) {
newOutput(filePath, encoding) {
var _a;
if (encoding === void 0) { encoding = ((_a = this._file) === null || _a === void 0 ? void 0 : _a.encoding) || "utf-8"; }
let outFile;

@@ -124,16 +112,4 @@ let lang;

}
/**
* Reads a file in this context.
*
* @param fileName The name of the file.
* @returns {SsgFile}
* @protected
*/
readFile(fileName) {
return fileName.endsWith(".html")
? HtmlSsgFile.read(this, fileName)
: SsgFile.read(this, fileName);
}
}
SsgContextImpl.CONTEXT_PREFIX = "$context.";
SsgContextImpl.DEFAULT_NAME = "Ssg";

@@ -13,3 +13,3 @@ import { SsgStep } from "../SsgStep.js";

protected contentsConfigs: ContentStepConfig<C>[];
protected output: OutputFunc;
protected write: OutputFunc;
/**

@@ -22,5 +22,5 @@ * Logger name

* @param contentsConfigs The content roots and associated replacements to perform.
* @param output The function that writes the output contents once they are ready.
* @param write The function that writes the output contents once they are ready.
*/
constructor(contentsConfigs: ContentStepConfig<C>[], output: OutputFunc);
constructor(contentsConfigs: ContentStepConfig<C>[], write: OutputFunc);
execute(context: C): Promise<ContentStepResult>;

@@ -27,0 +27,0 @@ protected processRoots(context: C, contentsConfig: ContentStepConfig): Promise<number>;

@@ -10,7 +10,7 @@ import fs from "fs";

* @param contentsConfigs The content roots and associated replacements to perform.
* @param output The function that writes the output contents once they are ready.
* @param write The function that writes the output contents once they are ready.
*/
constructor(contentsConfigs, output) {
constructor(contentsConfigs, write) {
this.contentsConfigs = contentsConfigs;
this.output = output;
this.write = write;
/**

@@ -61,13 +61,17 @@ * Logger name

async processFile(context, filePath, contentsConfig) {
context.debug("Processing file", filePath);
context.file = context.getInputFrom(filePath);
const outputPath = contentsConfig.getOutputFile(context);
const outputFile = context.getOutputFrom(outputPath);
context.file = context.read(filePath);
const processed = this.shouldProcess(context, contentsConfig);
if (processed) {
context.debug("Processing", filePath);
for (const replacement of contentsConfig.replacements) {
await replacement.execute(context);
}
await this.output(context, outputFile);
const outputPath = contentsConfig.getOutputPath(context);
const output = context.newOutput(outputPath);
context.debug("Writing", output.name);
await this.write(context, output);
}
else {
context.debug("Not orocessing", filePath);
}
return processed;

@@ -86,3 +90,3 @@ }

let inputHasChanged;
const outputPath = contentsConfig.getOutputFile(context);
const outputPath = contentsConfig.getOutputPath(context);
const outputExists = fs.existsSync(outputPath);

@@ -89,0 +93,0 @@ if (outputExists) {

import { SsgContext } from "../../SsgContext";
import { ReplaceCommand } from "./replace";
export type ContentStepConfig<C extends SsgContext = SsgContext> = {
import { SsgConfig } from "../../SsgConfig";
export interface ContentStepConfig<C extends SsgContext = SsgContext> extends SsgConfig {
/**

@@ -12,7 +13,2 @@ * The glob roots of contents to process.

replacements: ReplaceCommand<C>[];
/**
* @param context
* @return the file where to output.
*/
getOutputFile(context: C): string;
};
}
import { RegexReplaceCommand } from "../../RegexReplaceCommand.js";
import { RegexReplacer } from "../../RegexReplacer.js";
import { SsgContext } from "../../../../../SsgContext.js";
/**
* Replaces by a value or another, depending on the evaluation of an expression.
* Syntax is SSI-like:
* <!--#if expr="someVar=someValue" -->result if true<!--#else-->result if false<!--#endif-->
*/
export declare class SsiIfReplaceCommand extends RegexReplaceCommand {

@@ -5,0 +10,0 @@ protected readonly replacer: {

import { RegexReplaceCommand } from "../../RegexReplaceCommand.js";
/**
* Replaces by a value or another, depending on the evaluation of an expression.
* Syntax is SSI-like:
* <!--#if expr="someVar=someValue" -->result if true<!--#else-->result if false<!--#endif-->
*/
export class SsiIfReplaceCommand extends RegexReplaceCommand {

@@ -3,0 +8,0 @@ constructor() {

@@ -1,4 +0,8 @@

import { RegexReplaceCommand } from '../../RegexReplaceCommand.js';
import { RegexReplacer } from '../../RegexReplacer.js';
import { SsgContext } from '../../../../../SsgContext.js';
import { RegexReplaceCommand } from "../../RegexReplaceCommand.js";
import { RegexReplacer } from "../../RegexReplacer.js";
import { SsgContext } from "../../../../../SsgContext.js";
/**
* Replaces a <!--*#config timefmt="someFormat"--><!--#flastmod virtual="\$DOCUMENT_URI"\s*-->
* by the datetime of modification of the current file.
*/
export declare class SsiLastModifiedReplaceCommand extends RegexReplaceCommand {

@@ -5,0 +9,0 @@ protected options: Intl.DateTimeFormatOptions;

@@ -1,2 +0,6 @@

import { RegexReplaceCommand } from '../../RegexReplaceCommand.js';
import { RegexReplaceCommand } from "../../RegexReplaceCommand.js";
/**
* Replaces a <!--*#config timefmt="someFormat"--><!--#flastmod virtual="\$DOCUMENT_URI"\s*-->
* by the datetime of modification of the current file.
*/
export class SsiLastModifiedReplaceCommand extends RegexReplaceCommand {

@@ -3,0 +7,0 @@ constructor(options) {

@@ -5,2 +5,6 @@ import { SsgStep } from './SsgStep.js';

import { SsgConfig } from '../SsgConfig';
export interface CopyStepConfig extends SsgConfig {
readonly copies: string[];
readonly options?: IOptions;
}
export type CopyStepResult = {

@@ -13,8 +17,6 @@ files: string[];

export declare class CopyStep<C extends SsgContext = SsgContext> implements SsgStep<C, CopyStepResult> {
protected copies: string[];
protected config: SsgConfig;
protected options?: IOptions | undefined;
protected config: CopyStepConfig;
readonly name = "copy";
constructor(copies: string[], config: SsgConfig, options?: IOptions | undefined);
constructor(config: CopyStepConfig);
execute(context: SsgContext): Promise<CopyStepResult>;
}

@@ -1,3 +0,4 @@

import { FileUtil } from '../util/index.js';
import * as process from 'process';
import { FileUtil } from "../util";
import path from "path";
/**

@@ -7,14 +8,13 @@ * Perform copies to out directory.

export class CopyStep {
constructor(copies, config, options) {
this.copies = copies;
constructor(config) {
this.config = config;
this.options = options;
this.name = 'copy';
}
async execute(context) {
const copies = this.copies;
const dest = this.config.outDir;
const copies = this.config.copies;
const destPath = this.config.getOutputPath(context);
const dest = path.dirname(destPath);
try {
context.log('Copying to', dest, copies);
const copiedFiles = await FileUtil.ssgCopy(dest, copies, this.options);
const copiedFiles = await FileUtil.ssgCopy(dest, copies, this.config.options);
const cwd = process.cwd();

@@ -21,0 +21,0 @@ const files = copiedFiles.map(file => file.startsWith(cwd) ? file.substring(cwd.length + 1) : file);

@@ -5,2 +5,16 @@ import { SsgStep } from "./SsgStep.js";

import { SsgFile } from "../util";
export interface DirectoryStepConfig extends SsgConfig {
/**
* A list of directories to look into.
*/
readonly rootDirs: string[];
/**
* A list of directories to avoid looking into.
*/
readonly excludedDirs: string[];
/**
* The name of the file containing the <--#echo var="directories"--> tag
*/
readonly templateFileName: string;
}
export interface DirectoryResult {

@@ -15,6 +29,3 @@ directoryCount: number;

export declare abstract class DirectoryStep<C extends SsgContext = SsgContext> implements SsgStep<C, DirectoryResult> {
readonly rootDirs: string[];
protected excludedDirs: string[];
protected templateFileName: string;
protected config: SsgConfig;
protected config: DirectoryStepConfig;
readonly name: string;

@@ -24,9 +35,6 @@ /**

*
* @param rootDirs A list of directories to look into.
* @param excludedDirs A list of directories to avoid looking into.
* @param templateFileName The name of the file containing the <--#echo var="directories"--> tag
* @param config The SSG configuration.
* @param config The step configuration.
* @param name The step name ("directory" by default)
*/
constructor(rootDirs: string[], excludedDirs: string[], templateFileName: string, config: SsgConfig, name?: string);
constructor(config: DirectoryStepConfig, name?: string);
/**

@@ -33,0 +41,0 @@ * Execute the directory step by:

@@ -1,2 +0,1 @@

import path from "path";
import { FileUtil } from "../util";

@@ -12,12 +11,6 @@ /**

*
* @param rootDirs A list of directories to look into.
* @param excludedDirs A list of directories to avoid looking into.
* @param templateFileName The name of the file containing the <--#echo var="directories"--> tag
* @param config The SSG configuration.
* @param config The step configuration.
* @param name The step name ("directory" by default)
*/
constructor(rootDirs, excludedDirs, templateFileName, config, name = "directory") {
this.rootDirs = rootDirs;
this.excludedDirs = excludedDirs;
this.templateFileName = templateFileName;
constructor(config, name = "directory") {
this.config = config;

@@ -33,7 +26,7 @@ this.name = name;

async execute(context) {
context.file = context.getInputFrom(this.templateFileName);
const outputFilePath = path.join(this.config.outDir, this.templateFileName);
const outputFile = context.getOutputFrom(outputFilePath);
const dirNames = (await this.findDirs(this.rootDirs))
.filter(dirName => !this.excludedDirs.includes(dirName));
context.file = context.read(this.config.templateFileName);
const outputFilePath = this.config.getOutputPath(context);
const outputFile = context.newOutput(outputFilePath);
const dirNames = (await this.findDirs(this.config.rootDirs))
.filter(dirName => !this.config.excludedDirs.includes(dirName));
await this.processDirs(context, dirNames, outputFile);

@@ -56,3 +49,3 @@ return { directoryCount: dirNames.length };

const dirs = (await this.findDirs([baseDir + "/"]))
.filter(dirName => !this.excludedDirs.includes(dirName));
.filter(dirName => !this.config.excludedDirs.includes(dirName));
for (const dir of dirs) {

@@ -59,0 +52,0 @@ subDirs = subDirs.concat(await this.findDirs([dir + "/*/"]));

@@ -1,5 +0,5 @@

import { TestRunner } from '@javarome/testscript';
let runner = new TestRunner(["**/*Test.ts"], ['node_modules/**/*.*']);
import { TestRunner } from "@javarome/testscript";
let runner = new TestRunner(["**/*Test.ts"], ["node_modules/**/*.*"]);
runner.run().then(result => {
console.log('Executed', result.suites.length, 'test suites in', runner.durationStr(result.duration));
});

@@ -5,3 +5,3 @@ {

"author": "Jérôme Beau <javarome@gmail.com> (https://javarome.com)",
"version": "1.8.0",
"version": "1.9.0",
"description": "Static Site Generation TypeScript API",

@@ -8,0 +8,0 @@ "exports": "./dist/src/index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc