@projectdochelp/s3te 3.0.0 → 3.1.1
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 +19 -17
- package/package.json +1 -1
- package/packages/cli/src/project.mjs +56 -1
package/README.md
CHANGED
|
@@ -136,9 +136,25 @@ cd mywebsite
|
|
|
136
136
|
</details>
|
|
137
137
|
|
|
138
138
|
<details>
|
|
139
|
-
<summary>2.
|
|
139
|
+
<summary>2. Install S3TE locally in the project</summary>
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
```bash
|
|
142
|
+
npm install --save-dev @projectdochelp/s3te
|
|
143
|
+
```
|
|
144
|
+
</details>
|
|
145
|
+
|
|
146
|
+
<details>
|
|
147
|
+
<summary>3. Scaffold the project</summary>
|
|
148
|
+
|
|
149
|
+
With the local package installed, initialize the project like this:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
npx s3te init --project-name mywebsite --base-url example.com
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
If `npm install` already created a minimal `package.json`, `s3te init` extends it with the missing S3TE defaults and scripts instead of failing.
|
|
156
|
+
|
|
157
|
+
If you want a one-shot scaffold without installing first, and `@projectdochelp/s3te` is already published on npm, this also works:
|
|
142
158
|
|
|
143
159
|
```bash
|
|
144
160
|
npx --package @projectdochelp/s3te s3te init --project-name mywebsite --base-url example.com
|
|
@@ -155,7 +171,7 @@ node packages/cli/bin/s3te.mjs init --dir ./mywebsite --project-name mywebsite -
|
|
|
155
171
|
</details>
|
|
156
172
|
|
|
157
173
|
<details>
|
|
158
|
-
<summary>
|
|
174
|
+
<summary>4. What the scaffold creates</summary>
|
|
159
175
|
|
|
160
176
|
The default scaffold creates:
|
|
161
177
|
|
|
@@ -181,20 +197,6 @@ mywebsite/
|
|
|
181
197
|
|
|
182
198
|
</details>
|
|
183
199
|
|
|
184
|
-
<details>
|
|
185
|
-
<summary>4. Install S3TE locally in the project</summary>
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
npm install --save-dev @projectdochelp/s3te
|
|
189
|
-
npx s3te --help
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
This is the recommended everyday setup. From this point on, you run the project-local version with `npx s3te ...`.
|
|
193
|
-
|
|
194
|
-
If you want to use the built-in test helpers in your own project tests, import them from the same package via `@projectdochelp/s3te/testkit`.
|
|
195
|
-
|
|
196
|
-
</details>
|
|
197
|
-
|
|
198
200
|
<details>
|
|
199
201
|
<summary>5. Fill in the real AWS values in <code>s3te.config.json</code></summary>
|
|
200
202
|
|
package/package.json
CHANGED
|
@@ -125,6 +125,10 @@ async function fileExists(targetPath) {
|
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
function isPlainObject(value) {
|
|
129
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
130
|
+
}
|
|
131
|
+
|
|
128
132
|
async function writeProjectFile(targetPath, body, force = false) {
|
|
129
133
|
if (!force && await fileExists(targetPath)) {
|
|
130
134
|
throw new Error(`Refusing to overwrite existing file: ${targetPath}`);
|
|
@@ -132,6 +136,57 @@ async function writeProjectFile(targetPath, body, force = false) {
|
|
|
132
136
|
await writeTextFile(targetPath, body);
|
|
133
137
|
}
|
|
134
138
|
|
|
139
|
+
function mergeProjectPackageJson(existingPackageJson, projectPackageJson) {
|
|
140
|
+
if (!isPlainObject(existingPackageJson)) {
|
|
141
|
+
throw new Error("Existing package.json must contain a JSON object.");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (existingPackageJson.scripts !== undefined && !isPlainObject(existingPackageJson.scripts)) {
|
|
145
|
+
throw new Error("Existing package.json must use an object for scripts.");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const mergedPackageJson = { ...existingPackageJson };
|
|
149
|
+
for (const [key, value] of Object.entries(projectPackageJson)) {
|
|
150
|
+
if (key === "scripts") {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (mergedPackageJson[key] === undefined) {
|
|
155
|
+
mergedPackageJson[key] = value;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const mergedScripts = { ...(mergedPackageJson.scripts ?? {}) };
|
|
160
|
+
for (const [name, command] of Object.entries(projectPackageJson.scripts ?? {})) {
|
|
161
|
+
if (mergedScripts[name] === undefined) {
|
|
162
|
+
mergedScripts[name] = command;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (Object.keys(mergedScripts).length > 0) {
|
|
167
|
+
mergedPackageJson.scripts = mergedScripts;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return mergedPackageJson;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function writeProjectPackageJson(targetPath, projectPackageJson, force = false) {
|
|
174
|
+
if (force || !await fileExists(targetPath)) {
|
|
175
|
+
await writeTextFile(targetPath, JSON.stringify(projectPackageJson, null, 2) + "\n");
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
let existingPackageJson;
|
|
180
|
+
try {
|
|
181
|
+
existingPackageJson = JSON.parse(await fs.readFile(targetPath, "utf8"));
|
|
182
|
+
} catch (error) {
|
|
183
|
+
throw new Error(`Existing package.json is not valid JSON: ${targetPath}`, { cause: error });
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const mergedPackageJson = mergeProjectPackageJson(existingPackageJson, projectPackageJson);
|
|
187
|
+
await writeTextFile(targetPath, JSON.stringify(mergedPackageJson, null, 2) + "\n");
|
|
188
|
+
}
|
|
189
|
+
|
|
135
190
|
async function loadRenderState(projectDir, environment) {
|
|
136
191
|
const statePath = path.join(projectDir, "offline", "S3TELocal", "render-state", `${environment}.json`);
|
|
137
192
|
try {
|
|
@@ -268,7 +323,7 @@ export async function scaffoldProject(projectDir, options = {}) {
|
|
|
268
323
|
}
|
|
269
324
|
};
|
|
270
325
|
|
|
271
|
-
await
|
|
326
|
+
await writeProjectPackageJson(path.join(projectDir, "package.json"), projectPackageJson, force);
|
|
272
327
|
await writeProjectFile(path.join(projectDir, "s3te.config.json"), JSON.stringify(config, null, 2) + "\n", force);
|
|
273
328
|
await writeProjectFile(path.join(projectDir, "offline", "schemas", "s3te.config.schema.json"), JSON.stringify(schemaTemplate(), null, 2) + "\n", force);
|
|
274
329
|
await writeProjectFile(path.join(projectDir, "app", "part", "head.part"), "<meta charset='utf-8'>\n<title>My S3TE Site</title>\n", force);
|