@silicajs/cli 0.3.0 → 0.4.0
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/dist/bin.js
CHANGED
|
@@ -22,14 +22,22 @@ function reportBrokenWikilinks(links) {
|
|
|
22
22
|
if (message) console.warn(message);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
// src/env.ts
|
|
26
|
+
import nextEnv from "@next/env";
|
|
27
|
+
function loadProjectEnv(projectRoot, mode) {
|
|
28
|
+
nextEnv.loadEnvConfig(projectRoot, mode === "development", console, true);
|
|
29
|
+
}
|
|
30
|
+
|
|
25
31
|
// src/materialize.ts
|
|
26
32
|
import path from "path";
|
|
27
33
|
import { createRequire } from "module";
|
|
34
|
+
import { execa } from "execa";
|
|
28
35
|
import fs from "fs-extra";
|
|
29
36
|
import { loadConfig } from "@silicajs/core";
|
|
30
37
|
import {
|
|
31
38
|
assistantModuleTemplate,
|
|
32
39
|
assistantRouteTemplate,
|
|
40
|
+
generatedAppPackageManifest,
|
|
33
41
|
getSilicaTemplates,
|
|
34
42
|
nextConfigTemplate,
|
|
35
43
|
packageJsonTemplate,
|
|
@@ -42,10 +50,11 @@ async function materializeNextApp(options = {}) {
|
|
|
42
50
|
const nextRoot = path.join(projectRoot, ".silica/next");
|
|
43
51
|
const publicRoot = path.join(nextRoot, "public");
|
|
44
52
|
const config = await loadConfig(projectRoot);
|
|
45
|
-
const configImport = await resolveUserConfigImport(projectRoot, nextRoot);
|
|
46
53
|
await fs.ensureDir(nextRoot);
|
|
47
54
|
await fs.remove(path.join(nextRoot, "app"));
|
|
55
|
+
await removeGeneratedInstallArtifacts(nextRoot);
|
|
48
56
|
await fs.ensureDir(publicRoot);
|
|
57
|
+
const configImport = await resolveUserConfigImport(projectRoot, nextRoot);
|
|
49
58
|
for (const template of getSilicaTemplates()) {
|
|
50
59
|
const destination = path.join(nextRoot, template.path);
|
|
51
60
|
await fs.ensureDir(path.dirname(destination));
|
|
@@ -81,21 +90,142 @@ async function materializeNextApp(options = {}) {
|
|
|
81
90
|
}
|
|
82
91
|
await fs.writeFile(
|
|
83
92
|
path.join(nextRoot, "package.json"),
|
|
84
|
-
packageJsonTemplate(
|
|
93
|
+
packageJsonTemplate(
|
|
94
|
+
...await makeGeneratedAppDependencies(projectRoot, nextRoot, config)
|
|
95
|
+
)
|
|
85
96
|
);
|
|
86
97
|
await fs.writeFile(
|
|
87
98
|
path.join(nextRoot, "tsconfig.json"),
|
|
88
|
-
`${tsconfigTemplate(
|
|
99
|
+
`${tsconfigTemplate(false)}
|
|
89
100
|
`
|
|
90
101
|
);
|
|
91
102
|
await fs.writeFile(
|
|
92
103
|
path.join(nextRoot, "next-env.d.ts"),
|
|
93
104
|
'/// <reference types="next" />\n/// <reference types="next/image-types/global" />\n'
|
|
94
105
|
);
|
|
95
|
-
await
|
|
106
|
+
await removeGeneratedEnvFiles(nextRoot);
|
|
96
107
|
await overlayPublic(projectRoot, publicRoot);
|
|
97
108
|
return nextRoot;
|
|
98
109
|
}
|
|
110
|
+
async function makeGeneratedAppDependencies(projectRoot, nextRoot, config) {
|
|
111
|
+
const projectPackage = await fs.readJson(
|
|
112
|
+
path.join(projectRoot, "package.json")
|
|
113
|
+
);
|
|
114
|
+
const packageVersions = collectPackageVersions(projectPackage);
|
|
115
|
+
const dependencies = {
|
|
116
|
+
...generatedAppPackageManifest.dependencies
|
|
117
|
+
};
|
|
118
|
+
const devDependencies = {
|
|
119
|
+
...generatedAppPackageManifest.devDependencies
|
|
120
|
+
};
|
|
121
|
+
const localPackagesRoot = path.join(nextRoot, ".silica-packages");
|
|
122
|
+
await fs.remove(localPackagesRoot);
|
|
123
|
+
for (const [packageName, version] of Object.entries(dependencies)) {
|
|
124
|
+
dependencies[packageName] = await resolveBakedDependency(
|
|
125
|
+
projectRoot,
|
|
126
|
+
nextRoot,
|
|
127
|
+
localPackagesRoot,
|
|
128
|
+
packageName,
|
|
129
|
+
version
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
const themePackage = packageNameFromSpecifier(
|
|
133
|
+
resolveThemePackageSpecifier(config.theme)
|
|
134
|
+
);
|
|
135
|
+
if (themePackage && !dependencies[themePackage]) {
|
|
136
|
+
dependencies[themePackage] = await resolveProjectDependency(
|
|
137
|
+
projectRoot,
|
|
138
|
+
nextRoot,
|
|
139
|
+
localPackagesRoot,
|
|
140
|
+
packageVersions,
|
|
141
|
+
themePackage
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
if (config.assistant) {
|
|
145
|
+
dependencies["@silicajs/assistant"] = await resolveProjectDependency(
|
|
146
|
+
projectRoot,
|
|
147
|
+
nextRoot,
|
|
148
|
+
localPackagesRoot,
|
|
149
|
+
packageVersions,
|
|
150
|
+
"@silicajs/assistant"
|
|
151
|
+
);
|
|
152
|
+
dependencies[config.assistant.provider.package] = await resolveProjectDependency(
|
|
153
|
+
projectRoot,
|
|
154
|
+
nextRoot,
|
|
155
|
+
localPackagesRoot,
|
|
156
|
+
packageVersions,
|
|
157
|
+
config.assistant.provider.package
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
return [dependencies, devDependencies];
|
|
161
|
+
}
|
|
162
|
+
async function resolveBakedDependency(projectRoot, nextRoot, localPackagesRoot, packageName, version) {
|
|
163
|
+
const packageRoot = resolveInstalledPackageRoot(projectRoot, packageName);
|
|
164
|
+
return await packLocalDependency(nextRoot, localPackagesRoot, packageRoot) ?? version;
|
|
165
|
+
}
|
|
166
|
+
async function resolveProjectDependency(projectRoot, nextRoot, localPackagesRoot, packageVersions, packageName) {
|
|
167
|
+
const version = packageVersions[packageName];
|
|
168
|
+
if (!version) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`Generated app dependency ${packageName} is missing from package.json.
|
|
171
|
+
Add ${packageName} to the project dependencies before running silica build.`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
return resolveBakedDependency(
|
|
175
|
+
projectRoot,
|
|
176
|
+
nextRoot,
|
|
177
|
+
localPackagesRoot,
|
|
178
|
+
packageName,
|
|
179
|
+
version
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
async function packLocalDependency(nextRoot, localPackagesRoot, packageRoot) {
|
|
183
|
+
if (!packageRoot || isNodeModulesPackage(packageRoot)) return void 0;
|
|
184
|
+
await fs.ensureDir(localPackagesRoot);
|
|
185
|
+
const { stdout } = await execa(
|
|
186
|
+
"npm",
|
|
187
|
+
["pack", packageRoot, "--json", "--pack-destination", localPackagesRoot],
|
|
188
|
+
{ cwd: nextRoot }
|
|
189
|
+
);
|
|
190
|
+
const [entry] = JSON.parse(stdout);
|
|
191
|
+
if (!entry) return void 0;
|
|
192
|
+
const tarballPath = path.isAbsolute(entry.filename) ? entry.filename : path.join(localPackagesRoot, entry.filename);
|
|
193
|
+
return `file:${relativePosixPath(nextRoot, tarballPath)}`;
|
|
194
|
+
}
|
|
195
|
+
function resolveInstalledPackageRoot(projectRoot, packageName) {
|
|
196
|
+
const require2 = createRequire(path.join(projectRoot, "package.json"));
|
|
197
|
+
for (const searchPath of require2.resolve.paths(packageName) ?? []) {
|
|
198
|
+
const packagePath = path.join(searchPath, packageName, "package.json");
|
|
199
|
+
if (!fs.existsSync(packagePath)) continue;
|
|
200
|
+
return fs.realpathSync(path.dirname(packagePath));
|
|
201
|
+
}
|
|
202
|
+
return void 0;
|
|
203
|
+
}
|
|
204
|
+
function isNodeModulesPackage(packageRoot) {
|
|
205
|
+
return packageRoot.split(path.sep).includes("node_modules");
|
|
206
|
+
}
|
|
207
|
+
function relativePosixPath(from, to) {
|
|
208
|
+
return path.relative(from, to).split(path.sep).join("/");
|
|
209
|
+
}
|
|
210
|
+
function collectPackageVersions(projectPackage) {
|
|
211
|
+
return {
|
|
212
|
+
...projectPackage.optionalDependencies,
|
|
213
|
+
...projectPackage.peerDependencies,
|
|
214
|
+
...projectPackage.devDependencies,
|
|
215
|
+
...projectPackage.dependencies
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function resolveThemePackageSpecifier(themeValue) {
|
|
219
|
+
const themeName = typeof themeValue === "object" && themeValue !== null && "name" in themeValue ? String(themeValue.name ?? "default") : typeof themeValue === "string" ? themeValue : "default";
|
|
220
|
+
if (!themeName || themeName === "default") return "@silicajs/theme-amethyst";
|
|
221
|
+
return themeName;
|
|
222
|
+
}
|
|
223
|
+
function packageNameFromSpecifier(specifier) {
|
|
224
|
+
if (specifier.startsWith(".") || specifier.startsWith("/")) return void 0;
|
|
225
|
+
const [first, second] = specifier.split("/");
|
|
226
|
+
if (!first) return void 0;
|
|
227
|
+
return first.startsWith("@") && second ? `${first}/${second}` : first;
|
|
228
|
+
}
|
|
99
229
|
function assertAssistantDependenciesInstalled(projectRoot, provider) {
|
|
100
230
|
if (!isPackageInstalled(projectRoot, "@silicajs/assistant")) {
|
|
101
231
|
throw new Error(
|
|
@@ -121,8 +251,9 @@ function isPackageInstalled(projectRoot, packageName) {
|
|
|
121
251
|
}
|
|
122
252
|
async function resolveUserConfigImport(projectRoot, nextRoot) {
|
|
123
253
|
const configPath = await findUserConfig(projectRoot);
|
|
254
|
+
await removeGeneratedUserConfig(nextRoot);
|
|
124
255
|
if (!configPath) return void 0;
|
|
125
|
-
const relativePath =
|
|
256
|
+
const relativePath = relativePosixPath(nextRoot, configPath);
|
|
126
257
|
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
127
258
|
}
|
|
128
259
|
async function findUserConfig(projectRoot) {
|
|
@@ -132,20 +263,29 @@ async function findUserConfig(projectRoot) {
|
|
|
132
263
|
}
|
|
133
264
|
return void 0;
|
|
134
265
|
}
|
|
135
|
-
async function
|
|
136
|
-
const entries = await fs.readdir(
|
|
137
|
-
|
|
138
|
-
(
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
266
|
+
async function removeGeneratedEnvFiles(nextRoot) {
|
|
267
|
+
const entries = await fs.readdir(nextRoot).catch(() => []);
|
|
268
|
+
await Promise.all(
|
|
269
|
+
entries.filter(isEnvFile).map((entry) => fs.remove(path.join(nextRoot, entry)))
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
async function removeGeneratedInstallArtifacts(nextRoot) {
|
|
273
|
+
await Promise.all([
|
|
274
|
+
fs.remove(path.join(nextRoot, "node_modules")),
|
|
275
|
+
fs.remove(path.join(nextRoot, "package-lock.json")),
|
|
276
|
+
fs.remove(path.join(nextRoot, "npm-shrinkwrap.json")),
|
|
277
|
+
fs.remove(path.join(nextRoot, "pnpm-lock.yaml")),
|
|
278
|
+
fs.remove(path.join(nextRoot, "yarn.lock"))
|
|
279
|
+
]);
|
|
280
|
+
}
|
|
281
|
+
async function removeGeneratedUserConfig(nextRoot) {
|
|
282
|
+
await Promise.all([
|
|
283
|
+
fs.remove(path.join(nextRoot, "silica.user.config.ts")),
|
|
284
|
+
fs.remove(path.join(nextRoot, "silica.user.config.js"))
|
|
285
|
+
]);
|
|
286
|
+
}
|
|
287
|
+
function isEnvFile(name) {
|
|
288
|
+
return name === ".env" || name.startsWith(".env.");
|
|
149
289
|
}
|
|
150
290
|
async function overlayPublic(projectRoot, publicRoot) {
|
|
151
291
|
const sourceRoot = path.join(projectRoot, "public");
|
|
@@ -156,21 +296,13 @@ async function overlayPublic(projectRoot, publicRoot) {
|
|
|
156
296
|
const source = path.join(sourceRoot, entry);
|
|
157
297
|
const destination = path.join(publicRoot, entry);
|
|
158
298
|
await fs.remove(destination);
|
|
159
|
-
|
|
160
|
-
await fs.symlink(
|
|
161
|
-
source,
|
|
162
|
-
destination,
|
|
163
|
-
(await fs.stat(source)).isDirectory() ? "dir" : "file"
|
|
164
|
-
);
|
|
165
|
-
} catch {
|
|
166
|
-
await fs.copy(source, destination);
|
|
167
|
-
}
|
|
299
|
+
await fs.copy(source, destination, { dereference: true });
|
|
168
300
|
}
|
|
169
301
|
}
|
|
170
302
|
|
|
171
303
|
// src/next.ts
|
|
172
304
|
import path2 from "path";
|
|
173
|
-
import { execa } from "execa";
|
|
305
|
+
import { execa as execa2 } from "execa";
|
|
174
306
|
import fs2 from "fs-extra";
|
|
175
307
|
import { loadConfig as loadConfig2 } from "@silicajs/core";
|
|
176
308
|
async function runNext(command, nextRoot) {
|
|
@@ -185,7 +317,7 @@ async function runStart(nextRoot) {
|
|
|
185
317
|
}
|
|
186
318
|
await prepareStandaloneAssets(nextRoot, standaloneServer);
|
|
187
319
|
installStackTraceRewrite(nextRoot);
|
|
188
|
-
const subprocess =
|
|
320
|
+
const subprocess = execa2("node", [standaloneServer], {
|
|
189
321
|
stdin: "inherit",
|
|
190
322
|
stdout: "pipe",
|
|
191
323
|
stderr: "pipe",
|
|
@@ -202,10 +334,11 @@ async function runStart(nextRoot) {
|
|
|
202
334
|
}
|
|
203
335
|
async function startNext(command, nextRoot) {
|
|
204
336
|
installStackTraceRewrite(nextRoot);
|
|
205
|
-
const subprocess =
|
|
337
|
+
const subprocess = execa2("next", [command], {
|
|
206
338
|
stdin: "inherit",
|
|
207
339
|
stdout: "pipe",
|
|
208
340
|
stderr: "pipe",
|
|
341
|
+
cwd: nextRoot,
|
|
209
342
|
env: await makeNextEnv()
|
|
210
343
|
});
|
|
211
344
|
subprocess.stdout?.on("data", (chunk) => {
|
|
@@ -231,6 +364,10 @@ async function prepareStandaloneAssets(nextRoot, standaloneServer) {
|
|
|
231
364
|
path2.join(nextRoot, "public"),
|
|
232
365
|
path2.join(serverRoot, "public")
|
|
233
366
|
);
|
|
367
|
+
await syncStandaloneAsset(
|
|
368
|
+
path2.join(nextRoot, "data"),
|
|
369
|
+
path2.join(serverRoot, "data")
|
|
370
|
+
);
|
|
234
371
|
}
|
|
235
372
|
function installStackTraceRewrite(nextRoot) {
|
|
236
373
|
const previous = Error.prepareStackTrace;
|
|
@@ -256,9 +393,10 @@ async function makeNextEnv() {
|
|
|
256
393
|
...config.auth?.allowedEmails ?? [],
|
|
257
394
|
...parseList(process.env.SILICA_ALLOWED_EMAILS)
|
|
258
395
|
]);
|
|
396
|
+
const env = { ...process.env };
|
|
397
|
+
delete env.__NEXT_PROCESSED_ENV;
|
|
259
398
|
return {
|
|
260
|
-
...
|
|
261
|
-
SILICA_PROJECT_ROOT: process.cwd(),
|
|
399
|
+
...env,
|
|
262
400
|
SILICA_AUTH_ENABLED: authEnabled ? "true" : "false",
|
|
263
401
|
SILICA_ALLOWED_DOMAINS: allowedDomains.join(","),
|
|
264
402
|
SILICA_ALLOWED_EMAILS: allowedEmails.join(",")
|
|
@@ -300,10 +438,10 @@ import fs3 from "fs-extra";
|
|
|
300
438
|
|
|
301
439
|
// src/scaffold-versions.ts
|
|
302
440
|
var scaffoldDependencyRanges = {
|
|
303
|
-
"@silicajs/cli": "^0.
|
|
304
|
-
"@silicajs/core": "^0.
|
|
305
|
-
"@silicajs/next": "^0.
|
|
306
|
-
"@silicajs/theme-amethyst": "^0.5.
|
|
441
|
+
"@silicajs/cli": "^0.4.0",
|
|
442
|
+
"@silicajs/core": "^0.9.0",
|
|
443
|
+
"@silicajs/next": "^0.6.0",
|
|
444
|
+
"@silicajs/theme-amethyst": "^0.5.1"
|
|
307
445
|
};
|
|
308
446
|
|
|
309
447
|
// src/scaffold.ts
|
|
@@ -367,6 +505,9 @@ export default defineConfig({
|
|
|
367
505
|
title: "My Silica Site",
|
|
368
506
|
description: "A private knowledge site",
|
|
369
507
|
theme: "default",
|
|
508
|
+
// Self-hosted via the included Dockerfile. Remove this to deploy to a managed
|
|
509
|
+
// platform such as Vercel and let its adapter manage caching.
|
|
510
|
+
render: { output: "standalone" },
|
|
370
511
|
// auth: {
|
|
371
512
|
// provider: "google",
|
|
372
513
|
// allowedDomains: ["example.com"],
|
|
@@ -477,7 +618,7 @@ Copy \`.env.example\` to \`.env\` and fill in Better Auth / Google OAuth values
|
|
|
477
618
|
|
|
478
619
|
## Docker
|
|
479
620
|
|
|
480
|
-
The scaffolded Dockerfile builds the generated standalone Next.js output and starts the traced \`server.js\` from wherever Next places it inside the standalone tree. Mount \`/app
|
|
621
|
+
The scaffolded Dockerfile builds the generated standalone Next.js output and starts the traced \`server.js\` from wherever Next places it inside the standalone tree. Mount \`/app/data/cache/next\` as a volume to preserve rendered-note cache entries across container replacement.
|
|
481
622
|
`;
|
|
482
623
|
}
|
|
483
624
|
function dockerfile() {
|
|
@@ -493,12 +634,21 @@ RUN npm run build
|
|
|
493
634
|
FROM node:22-alpine AS runner
|
|
494
635
|
WORKDIR /app
|
|
495
636
|
ENV NODE_ENV=production
|
|
496
|
-
ENV
|
|
497
|
-
ENV SILICA_CACHE_DIR=/app/.silica/cache/next
|
|
637
|
+
ENV SILICA_CACHE_DIR=/app/data/cache/next
|
|
498
638
|
COPY --from=build /app/.silica/next/.next/standalone ./
|
|
499
|
-
COPY --from=build /app/.silica/next/.next/static ./.silica
|
|
500
|
-
COPY --from=build /app/.silica/next/public ./.silica/
|
|
501
|
-
COPY --from=build /app/.silica ./.silica
|
|
639
|
+
COPY --from=build /app/.silica/next/.next/static ./.silica-standalone-assets/.next/static
|
|
640
|
+
COPY --from=build /app/.silica/next/public ./.silica-standalone-assets/public
|
|
641
|
+
COPY --from=build /app/.silica/next/data ./.silica-standalone-assets/data
|
|
642
|
+
RUN set -eux; \\
|
|
643
|
+
server_file="$(find . -path '*/server.js' -print -quit)"; \\
|
|
644
|
+
test -n "$server_file"; \\
|
|
645
|
+
server_dir="$(dirname "$server_file")"; \\
|
|
646
|
+
rm -rf "$server_dir/.next/static" "$server_dir/public" "$server_dir/data"; \\
|
|
647
|
+
mkdir -p "$server_dir/.next"; \\
|
|
648
|
+
cp -R .silica-standalone-assets/.next/static "$server_dir/.next/static"; \\
|
|
649
|
+
cp -R .silica-standalone-assets/public "$server_dir/public"; \\
|
|
650
|
+
cp -R .silica-standalone-assets/data "$server_dir/data"; \\
|
|
651
|
+
rm -rf .silica-standalone-assets
|
|
502
652
|
EXPOSE 3000
|
|
503
653
|
CMD ["sh", "-c", "node $(find . -path '*/server.js' -print -quit)"]
|
|
504
654
|
`;
|
|
@@ -601,7 +751,7 @@ function watchContent({
|
|
|
601
751
|
return watcher;
|
|
602
752
|
}
|
|
603
753
|
async function readRenderHashes(projectRoot) {
|
|
604
|
-
const databasePath = path4.join(projectRoot, ".silica/vault.db");
|
|
754
|
+
const databasePath = path4.join(projectRoot, ".silica/next/data/vault.db");
|
|
605
755
|
if (!await fs4.pathExists(databasePath)) return /* @__PURE__ */ new Map();
|
|
606
756
|
const db = new Database(databasePath, {
|
|
607
757
|
fileMustExist: true,
|
|
@@ -641,6 +791,7 @@ async function createCommand(directory) {
|
|
|
641
791
|
}
|
|
642
792
|
async function devCommand() {
|
|
643
793
|
const projectRoot = process.cwd();
|
|
794
|
+
loadProjectEnv(projectRoot, "development");
|
|
644
795
|
let shouldRestart = true;
|
|
645
796
|
while (shouldRestart) {
|
|
646
797
|
shouldRestart = false;
|
|
@@ -668,13 +819,16 @@ async function devCommand() {
|
|
|
668
819
|
}
|
|
669
820
|
async function buildCommand() {
|
|
670
821
|
const projectRoot = process.cwd();
|
|
822
|
+
loadProjectEnv(projectRoot, "production");
|
|
671
823
|
const nextRoot = await materializeNextApp({ projectRoot });
|
|
672
824
|
const result = await precompute2({ projectRoot });
|
|
673
825
|
reportBrokenWikilinks(result.brokenLinks);
|
|
674
826
|
await runNext("build", nextRoot);
|
|
675
827
|
}
|
|
676
828
|
async function startCommand() {
|
|
677
|
-
const
|
|
829
|
+
const projectRoot = process.cwd();
|
|
830
|
+
loadProjectEnv(projectRoot, "production");
|
|
831
|
+
const nextRoot = await materializeNextApp({ projectRoot });
|
|
678
832
|
await runStart(nextRoot);
|
|
679
833
|
}
|
|
680
834
|
|
|
@@ -704,4 +858,4 @@ export {
|
|
|
704
858
|
startCommand,
|
|
705
859
|
main
|
|
706
860
|
};
|
|
707
|
-
//# sourceMappingURL=chunk-
|
|
861
|
+
//# sourceMappingURL=chunk-FD4I5Q53.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands.ts","../src/diagnostics.ts","../src/env.ts","../src/materialize.ts","../src/next.ts","../src/scaffold.ts","../src/scaffold-versions.ts","../src/watch.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport {\n buildCommand,\n createCommand,\n devCommand,\n startCommand,\n} from \"./commands.js\";\n\nexport {\n buildCommand,\n createCommand,\n devCommand,\n startCommand,\n} from \"./commands.js\";\n\nexport async function main(argv = process.argv): Promise<void> {\n const program = new Command();\n program\n .name(\"silica\")\n .description(\"Publish an Obsidian-flavored markdown vault with Next.js.\")\n .version(\"0.1.0\");\n\n program\n .command(\"create\")\n .argument(\"<directory>\", \"directory to create\")\n .description(\"scaffold a new Silica vault\")\n .action(async (directory: string) => {\n await createCommand(directory);\n });\n\n program\n .command(\"dev\")\n .description(\"materialize the hidden Next.js app and start development\")\n .action(async () => {\n await devCommand();\n });\n\n program\n .command(\"build\")\n .description(\"precompute content and build the hidden Next.js app\")\n .action(async () => {\n await buildCommand();\n });\n\n program\n .command(\"start\")\n .description(\"start the built hidden Next.js app\")\n .action(async () => {\n await startCommand();\n });\n\n await program.parseAsync(argv);\n}\n","import crypto from \"node:crypto\";\nimport { precompute } from \"@silicajs/core\";\nimport { reportBrokenWikilinks } from \"./diagnostics.js\";\nimport { loadProjectEnv } from \"./env.js\";\nimport { materializeNextApp } from \"./materialize.js\";\nimport { runNext, runStart, startNext } from \"./next.js\";\nimport { scaffoldProject } from \"./scaffold.js\";\nimport { resolveDevPort, watchContent } from \"./watch.js\";\n\nexport async function createCommand(directory: string): Promise<void> {\n await scaffoldProject(directory);\n console.log(`[silica] created ${directory}`);\n}\n\nexport async function devCommand(): Promise<void> {\n const projectRoot = process.cwd();\n loadProjectEnv(projectRoot, \"development\");\n let shouldRestart = true;\n\n while (shouldRestart) {\n shouldRestart = false;\n process.env.SILICA_REVALIDATE_SECRET ??= crypto.randomUUID();\n const nextRoot = await materializeNextApp({ projectRoot });\n await precompute({ projectRoot });\n const { subprocess } = await startNext(\"dev\", nextRoot);\n const watcher = watchContent({\n projectRoot,\n port: resolveDevPort(),\n onConfigChange: async () => {\n console.log(\"[silica] config or theme changed; restarting Next.js\");\n shouldRestart = true;\n subprocess.kill(\"SIGTERM\");\n },\n });\n\n try {\n await subprocess;\n } catch (error) {\n if (!shouldRestart) throw error;\n } finally {\n await watcher.close();\n }\n }\n}\n\nexport async function buildCommand(): Promise<void> {\n const projectRoot = process.cwd();\n loadProjectEnv(projectRoot, \"production\");\n const nextRoot = await materializeNextApp({ projectRoot });\n const result = await precompute({ projectRoot });\n reportBrokenWikilinks(result.brokenLinks);\n await runNext(\"build\", nextRoot);\n}\n\nexport async function startCommand(): Promise<void> {\n const projectRoot = process.cwd();\n loadProjectEnv(projectRoot, \"production\");\n const nextRoot = await materializeNextApp({ projectRoot });\n await runStart(nextRoot);\n}\n","export type BrokenLinkDiagnostic = {\n source: string;\n target: string;\n};\n\nexport function formatBrokenWikilinks(links: BrokenLinkDiagnostic[]): string {\n if (links.length === 0) return \"\";\n return [\n \"[silica] broken wikilinks:\",\n ...links\n .slice()\n .sort((a, b) =>\n `${a.source}\\0${a.target}`.localeCompare(`${b.source}\\0${b.target}`),\n )\n .map((link) => ` ${link.source} -> ${link.target}`),\n ].join(\"\\n\");\n}\n\nexport function reportBrokenWikilinks(links: BrokenLinkDiagnostic[]): void {\n const message = formatBrokenWikilinks(links);\n if (message) console.warn(message);\n}\n","import nextEnv from \"@next/env\";\n\nexport type ProjectEnvMode = \"development\" | \"production\";\n\nexport function loadProjectEnv(\n projectRoot: string,\n mode: ProjectEnvMode,\n): void {\n nextEnv.loadEnvConfig(projectRoot, mode === \"development\", console, true);\n}\n","import path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { execa } from \"execa\";\nimport fs from \"fs-extra\";\nimport { loadConfig } from \"@silicajs/core\";\nimport {\n assistantModuleTemplate,\n assistantRouteTemplate,\n generatedAppPackageManifest,\n getSilicaTemplates,\n nextConfigTemplate,\n packageJsonTemplate,\n proxyTemplate,\n themeModuleTemplate,\n tsconfigTemplate,\n} from \"@silicajs/next\";\n\nexport type MaterializeOptions = {\n projectRoot?: string;\n};\n\ntype ProjectPackageJson = {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n};\n\ntype NpmPackEntry = {\n filename: string;\n};\n\ntype GeneratedAppPackageDependencies = {\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n};\n\nexport async function materializeNextApp(\n options: MaterializeOptions = {},\n): Promise<string> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const nextRoot = path.join(projectRoot, \".silica/next\");\n const publicRoot = path.join(nextRoot, \"public\");\n const config = await loadConfig(projectRoot);\n\n await fs.ensureDir(nextRoot);\n await fs.remove(path.join(nextRoot, \"app\"));\n await removeGeneratedInstallArtifacts(nextRoot);\n await fs.ensureDir(publicRoot);\n const configImport = await resolveUserConfigImport(projectRoot, nextRoot);\n\n for (const template of getSilicaTemplates()) {\n const destination = path.join(nextRoot, template.path);\n await fs.ensureDir(path.dirname(destination));\n await fs.writeFile(destination, template.content);\n }\n\n await fs.writeFile(\n path.join(nextRoot, \"next.config.ts\"),\n nextConfigTemplate(configImport),\n );\n await fs.writeFile(path.join(nextRoot, \"proxy.ts\"), proxyTemplate(config));\n await fs.writeFile(\n path.join(nextRoot, \"silica-theme.ts\"),\n themeModuleTemplate(config.theme),\n );\n await fs.writeFile(\n path.join(nextRoot, \"silica-assistant.ts\"),\n assistantModuleTemplate(Boolean(config.assistant)),\n );\n if (config.assistant) {\n assertAssistantDependenciesInstalled(\n projectRoot,\n config.assistant.provider,\n );\n const assistantRoutePath = path.join(\n nextRoot,\n \"app/api/assistant/route.ts\",\n );\n await fs.ensureDir(path.dirname(assistantRoutePath));\n await fs.writeFile(\n assistantRoutePath,\n assistantRouteTemplate(config.assistant),\n );\n }\n await fs.writeFile(\n path.join(nextRoot, \"package.json\"),\n packageJsonTemplate(\n ...(await makeGeneratedAppDependencies(projectRoot, nextRoot, config)),\n ),\n );\n await fs.writeFile(\n path.join(nextRoot, \"tsconfig.json\"),\n `${tsconfigTemplate(false)}\\n`,\n );\n await fs.writeFile(\n path.join(nextRoot, \"next-env.d.ts\"),\n '/// <reference types=\"next\" />\\n/// <reference types=\"next/image-types/global\" />\\n',\n );\n await removeGeneratedEnvFiles(nextRoot);\n await overlayPublic(projectRoot, publicRoot);\n return nextRoot;\n}\n\nasync function makeGeneratedAppDependencies(\n projectRoot: string,\n nextRoot: string,\n config: Awaited<ReturnType<typeof loadConfig>>,\n): Promise<\n [\n dependencies: GeneratedAppPackageDependencies[\"dependencies\"],\n devDependencies: GeneratedAppPackageDependencies[\"devDependencies\"],\n ]\n> {\n const projectPackage = (await fs.readJson(\n path.join(projectRoot, \"package.json\"),\n )) as ProjectPackageJson;\n const packageVersions = collectPackageVersions(projectPackage);\n const dependencies: Record<string, string> = {\n ...generatedAppPackageManifest.dependencies,\n };\n const devDependencies: Record<string, string> = {\n ...generatedAppPackageManifest.devDependencies,\n };\n const localPackagesRoot = path.join(nextRoot, \".silica-packages\");\n await fs.remove(localPackagesRoot);\n for (const [packageName, version] of Object.entries(dependencies)) {\n dependencies[packageName] = await resolveBakedDependency(\n projectRoot,\n nextRoot,\n localPackagesRoot,\n packageName,\n version,\n );\n }\n\n const themePackage = packageNameFromSpecifier(\n resolveThemePackageSpecifier(config.theme),\n );\n if (themePackage && !dependencies[themePackage]) {\n dependencies[themePackage] = await resolveProjectDependency(\n projectRoot,\n nextRoot,\n localPackagesRoot,\n packageVersions,\n themePackage,\n );\n }\n\n if (config.assistant) {\n dependencies[\"@silicajs/assistant\"] = await resolveProjectDependency(\n projectRoot,\n nextRoot,\n localPackagesRoot,\n packageVersions,\n \"@silicajs/assistant\",\n );\n dependencies[config.assistant.provider.package] =\n await resolveProjectDependency(\n projectRoot,\n nextRoot,\n localPackagesRoot,\n packageVersions,\n config.assistant.provider.package,\n );\n }\n\n return [dependencies, devDependencies];\n}\n\nasync function resolveBakedDependency(\n projectRoot: string,\n nextRoot: string,\n localPackagesRoot: string,\n packageName: string,\n version: string,\n): Promise<string> {\n const packageRoot = resolveInstalledPackageRoot(projectRoot, packageName);\n return (\n (await packLocalDependency(nextRoot, localPackagesRoot, packageRoot)) ??\n version\n );\n}\n\nasync function resolveProjectDependency(\n projectRoot: string,\n nextRoot: string,\n localPackagesRoot: string,\n packageVersions: Record<string, string>,\n packageName: string,\n): Promise<string> {\n const version = packageVersions[packageName];\n if (!version) {\n throw new Error(\n `Generated app dependency ${packageName} is missing from package.json.\\n` +\n `Add ${packageName} to the project dependencies before running silica build.`,\n );\n }\n return resolveBakedDependency(\n projectRoot,\n nextRoot,\n localPackagesRoot,\n packageName,\n version,\n );\n}\n\nasync function packLocalDependency(\n nextRoot: string,\n localPackagesRoot: string,\n packageRoot: string | undefined,\n): Promise<string | undefined> {\n if (!packageRoot || isNodeModulesPackage(packageRoot)) return undefined;\n\n await fs.ensureDir(localPackagesRoot);\n const { stdout } = await execa(\n \"npm\",\n [\"pack\", packageRoot, \"--json\", \"--pack-destination\", localPackagesRoot],\n { cwd: nextRoot },\n );\n const [entry] = JSON.parse(stdout) as NpmPackEntry[];\n if (!entry) return undefined;\n\n const tarballPath = path.isAbsolute(entry.filename)\n ? entry.filename\n : path.join(localPackagesRoot, entry.filename);\n return `file:${relativePosixPath(nextRoot, tarballPath)}`;\n}\n\nfunction resolveInstalledPackageRoot(\n projectRoot: string,\n packageName: string,\n): string | undefined {\n const require = createRequire(path.join(projectRoot, \"package.json\"));\n for (const searchPath of require.resolve.paths(packageName) ?? []) {\n const packagePath = path.join(searchPath, packageName, \"package.json\");\n if (!fs.existsSync(packagePath)) continue;\n\n return fs.realpathSync(path.dirname(packagePath));\n }\n return undefined;\n}\n\nfunction isNodeModulesPackage(packageRoot: string): boolean {\n return packageRoot.split(path.sep).includes(\"node_modules\");\n}\n\nfunction relativePosixPath(from: string, to: string): string {\n return path.relative(from, to).split(path.sep).join(\"/\");\n}\n\nfunction collectPackageVersions(\n projectPackage: ProjectPackageJson,\n): Record<string, string> {\n return {\n ...projectPackage.optionalDependencies,\n ...projectPackage.peerDependencies,\n ...projectPackage.devDependencies,\n ...projectPackage.dependencies,\n };\n}\n\nfunction resolveThemePackageSpecifier(themeValue: unknown): string {\n const themeName =\n typeof themeValue === \"object\" &&\n themeValue !== null &&\n \"name\" in themeValue\n ? String((themeValue as { name?: string }).name ?? \"default\")\n : typeof themeValue === \"string\"\n ? themeValue\n : \"default\";\n\n if (!themeName || themeName === \"default\") return \"@silicajs/theme-amethyst\";\n return themeName;\n}\n\nfunction packageNameFromSpecifier(specifier: string): string | undefined {\n if (specifier.startsWith(\".\") || specifier.startsWith(\"/\")) return undefined;\n const [first, second] = specifier.split(\"/\");\n if (!first) return undefined;\n return first.startsWith(\"@\") && second ? `${first}/${second}` : first;\n}\n\nfunction assertAssistantDependenciesInstalled(\n projectRoot: string,\n provider: { package: string },\n): void {\n if (!isPackageInstalled(projectRoot, \"@silicajs/assistant\")) {\n throw new Error(\n \"Assistant is enabled in silica.config.ts but @silicajs/assistant is not installed.\\n\" +\n \"Install it together with the provider package for your configured model, e.g.:\\n\" +\n \" npm install @silicajs/assistant @core-ai/openai\",\n );\n }\n\n if (!isPackageInstalled(projectRoot, provider.package)) {\n throw new Error(\n `Assistant is enabled in silica.config.ts but ${provider.package} is not installed.\\n` +\n \"Install it together with @silicajs/assistant for your configured model, e.g.:\\n\" +\n ` npm install @silicajs/assistant ${provider.package}`,\n );\n }\n}\n\nfunction isPackageInstalled(projectRoot: string, packageName: string): boolean {\n const require = createRequire(path.join(projectRoot, \"package.json\"));\n for (const searchPath of require.resolve.paths(packageName) ?? []) {\n if (fs.existsSync(path.join(searchPath, packageName, \"package.json\"))) {\n return true;\n }\n }\n return false;\n}\n\nasync function resolveUserConfigImport(\n projectRoot: string,\n nextRoot: string,\n): Promise<string | undefined> {\n const configPath = await findUserConfig(projectRoot);\n await removeGeneratedUserConfig(nextRoot);\n if (!configPath) return undefined;\n\n const relativePath = relativePosixPath(nextRoot, configPath);\n return relativePath.startsWith(\".\") ? relativePath : `./${relativePath}`;\n}\n\nasync function findUserConfig(\n projectRoot: string,\n): Promise<string | undefined> {\n for (const filename of [\"silica.config.ts\", \"silica.config.js\"]) {\n const configPath = path.join(projectRoot, filename);\n if (await fs.pathExists(configPath)) return configPath;\n }\n return undefined;\n}\n\nasync function removeGeneratedEnvFiles(nextRoot: string): Promise<void> {\n const entries = await fs.readdir(nextRoot).catch(() => []);\n await Promise.all(\n entries\n .filter(isEnvFile)\n .map((entry) => fs.remove(path.join(nextRoot, entry))),\n );\n}\n\nasync function removeGeneratedInstallArtifacts(\n nextRoot: string,\n): Promise<void> {\n await Promise.all([\n fs.remove(path.join(nextRoot, \"node_modules\")),\n fs.remove(path.join(nextRoot, \"package-lock.json\")),\n fs.remove(path.join(nextRoot, \"npm-shrinkwrap.json\")),\n fs.remove(path.join(nextRoot, \"pnpm-lock.yaml\")),\n fs.remove(path.join(nextRoot, \"yarn.lock\")),\n ]);\n}\n\nasync function removeGeneratedUserConfig(nextRoot: string): Promise<void> {\n await Promise.all([\n fs.remove(path.join(nextRoot, \"silica.user.config.ts\")),\n fs.remove(path.join(nextRoot, \"silica.user.config.js\")),\n ]);\n}\n\nfunction isEnvFile(name: string): boolean {\n return name === \".env\" || name.startsWith(\".env.\");\n}\n\nasync function overlayPublic(\n projectRoot: string,\n publicRoot: string,\n): Promise<void> {\n const sourceRoot = path.join(projectRoot, \"public\");\n if (!(await fs.pathExists(sourceRoot))) return;\n await fs.ensureDir(publicRoot);\n for (const entry of await fs.readdir(sourceRoot)) {\n if (entry === \"silica\") continue;\n const source = path.join(sourceRoot, entry);\n const destination = path.join(publicRoot, entry);\n await fs.remove(destination);\n await fs.copy(source, destination, { dereference: true });\n }\n}\n","import path from \"node:path\";\nimport { execa, type ResultPromise } from \"execa\";\nimport fs from \"fs-extra\";\nimport { loadConfig } from \"@silicajs/core\";\n\nexport type NextCommand = \"dev\" | \"build\" | \"start\";\nexport type NextSubprocess = {\n subprocess: ResultPromise;\n};\n\nexport async function runNext(\n command: NextCommand,\n nextRoot: string,\n): Promise<void> {\n const { subprocess } = await startNext(command, nextRoot);\n await subprocess;\n}\n\nexport async function runStart(nextRoot: string): Promise<void> {\n const standaloneServer = await findStandaloneServer(nextRoot);\n if (!standaloneServer) {\n await runNext(\"start\", nextRoot);\n return;\n }\n\n await prepareStandaloneAssets(nextRoot, standaloneServer);\n installStackTraceRewrite(nextRoot);\n const subprocess = execa(\"node\", [standaloneServer], {\n stdin: \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n cwd: path.dirname(standaloneServer),\n env: await makeNextEnv(),\n });\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => {\n process.stdout.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n subprocess.stderr?.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n await subprocess;\n}\n\nexport async function startNext(\n command: NextCommand,\n nextRoot: string,\n): Promise<NextSubprocess> {\n installStackTraceRewrite(nextRoot);\n const subprocess = execa(\"next\", [command], {\n stdin: \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n cwd: nextRoot,\n env: await makeNextEnv(),\n });\n\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => {\n process.stdout.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n subprocess.stderr?.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n\n return { subprocess };\n}\n\nexport async function findStandaloneServer(\n nextRoot: string,\n): Promise<string | undefined> {\n const standaloneRoot = path.join(nextRoot, \".next/standalone\");\n if (!(await fs.pathExists(standaloneRoot))) return undefined;\n return findFile(standaloneRoot, \"server.js\");\n}\n\nexport async function prepareStandaloneAssets(\n nextRoot: string,\n standaloneServer: string,\n): Promise<void> {\n const serverRoot = path.dirname(standaloneServer);\n await syncStandaloneAsset(\n path.join(nextRoot, \".next/static\"),\n path.join(serverRoot, \".next/static\"),\n );\n await syncStandaloneAsset(\n path.join(nextRoot, \"public\"),\n path.join(serverRoot, \"public\"),\n );\n await syncStandaloneAsset(\n path.join(nextRoot, \"data\"),\n path.join(serverRoot, \"data\"),\n );\n}\n\nexport function installStackTraceRewrite(nextRoot: string): void {\n const previous = Error.prepareStackTrace;\n Error.prepareStackTrace = (error, stack) => {\n const rendered = previous\n ? previous(error, stack)\n : `${error.name}: ${error.message}\\n${stack.join(\"\\n\")}`;\n return rewriteFrameworkPaths(String(rendered), nextRoot);\n };\n}\n\nexport function rewriteFrameworkPaths(\n output: string,\n nextRoot: string,\n): string {\n const normalizedRoot = nextRoot.replace(/\\\\/g, \"/\");\n const escapedWindowsRoot = normalizedRoot.replace(/\\//g, \"\\\\\");\n return output\n .replaceAll(`${normalizedRoot}/app/`, \"@silicajs/next [route]/\")\n .replaceAll(`${escapedWindowsRoot}\\\\app\\\\`, \"@silicajs/next [route]\\\\\")\n .replaceAll(`${normalizedRoot}/`, \".silica/next/\")\n .replaceAll(`${escapedWindowsRoot}\\\\`, \".silica\\\\next\\\\\");\n}\n\nasync function makeNextEnv(): Promise<NodeJS.ProcessEnv> {\n const config = await loadConfig(process.cwd());\n const authEnabled =\n Boolean(config.auth) || process.env.SILICA_AUTH_ENABLED === \"true\";\n const allowedDomains = uniqueList([\n ...(config.auth?.allowedDomains ?? []),\n ...parseList(process.env.SILICA_ALLOWED_DOMAINS),\n ]);\n const allowedEmails = uniqueList([\n ...(config.auth?.allowedEmails ?? []),\n ...parseList(process.env.SILICA_ALLOWED_EMAILS),\n ]);\n const env = { ...process.env };\n delete env.__NEXT_PROCESSED_ENV;\n\n return {\n ...env,\n SILICA_AUTH_ENABLED: authEnabled ? \"true\" : \"false\",\n SILICA_ALLOWED_DOMAINS: allowedDomains.join(\",\"),\n SILICA_ALLOWED_EMAILS: allowedEmails.join(\",\"),\n };\n}\n\nfunction parseList(value: string | undefined): string[] {\n return value\n ? value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean)\n : [];\n}\n\nfunction uniqueList(values: readonly string[]): string[] {\n return [...new Set(values.map((item) => item.trim()).filter(Boolean))];\n}\n\nasync function syncStandaloneAsset(\n source: string,\n destination: string,\n): Promise<void> {\n if (!(await fs.pathExists(source))) return;\n if (path.resolve(source) === path.resolve(destination)) return;\n\n await fs.remove(destination);\n await fs.ensureDir(path.dirname(destination));\n try {\n await fs.symlink(source, destination, \"dir\");\n } catch {\n await fs.copy(source, destination);\n }\n}\n\nasync function findFile(\n root: string,\n filename: string,\n): Promise<string | undefined> {\n const entries = await fs.readdir(root, { withFileTypes: true });\n for (const entry of entries) {\n const absolute = path.join(root, entry.name);\n if (entry.isFile() && entry.name === filename) return absolute;\n if (entry.isDirectory()) {\n const found = await findFile(absolute, filename);\n if (found) return found;\n }\n }\n return undefined;\n}\n","import path from \"node:path\";\nimport fs from \"fs-extra\";\nimport { scaffoldDependencyRanges } from \"./scaffold-versions.js\";\n\nexport async function scaffoldProject(targetDir: string): Promise<void> {\n const root = path.resolve(targetDir);\n if ((await fs.pathExists(root)) && (await fs.readdir(root)).length > 0) {\n throw new Error(`Target directory is not empty: ${root}`);\n }\n\n await fs.ensureDir(path.join(root, \"content/notes\"));\n await fs.ensureDir(path.join(root, \".github/workflows\"));\n await fs.writeFile(path.join(root, \"content/index.md\"), indexMarkdown());\n await fs.writeFile(\n path.join(root, \"content/notes/getting-started.md\"),\n gettingStartedMarkdown(),\n );\n await fs.writeFile(path.join(root, \"silica.config.ts\"), silicaConfig());\n await fs.writeFile(path.join(root, \"tsconfig.json\"), tsconfig());\n await fs.writeFile(\n path.join(root, \"package.json\"),\n packageJson(path.basename(root)),\n );\n await fs.writeFile(path.join(root, \".env.example\"), envExample());\n await fs.writeFile(path.join(root, \".gitignore\"), gitignore());\n await fs.writeFile(path.join(root, \".dockerignore\"), dockerignore());\n await fs.writeFile(path.join(root, \"README.md\"), readme(path.basename(root)));\n await fs.writeFile(path.join(root, \"Dockerfile\"), dockerfile());\n await fs.writeFile(\n path.join(root, \".github/workflows/deploy.yml\"),\n workflow(),\n );\n}\n\nfunction indexMarkdown(): string {\n return `---\\ntitle: Welcome\\ntags: [home]\\n---\\n\\n# Welcome\\n\\nThis is your new Silica vault. Open [[notes/getting-started|Getting started]] to learn the basics.\\n\\n> [!note] Edit freely\\n> Write standard Markdown plus Obsidian-style wikilinks.\\n`;\n}\n\nfunction gettingStartedMarkdown(): string {\n return `---\\ntitle: Getting started\\ntags: [guide]\\n---\\n\\n# Getting started\\n\\nRun \\`npm run dev\\` and edit files in \\`content/\\`. Silica regenerates the hidden Next.js app under \\`.silica/\\`.\\n`;\n}\n\nfunction silicaConfig(): string {\n return `import { defineConfig } from \"@silicajs/core\";\\n\\nexport default defineConfig({\\n title: \"My Silica Site\",\\n description: \"A private knowledge site\",\\n theme: \"default\",\\n // Self-hosted via the included Dockerfile. Remove this to deploy to a managed\\n // platform such as Vercel and let its adapter manage caching.\\n render: { output: \"standalone\" },\\n // auth: {\\n // provider: \"google\",\\n // allowedDomains: [\"example.com\"],\\n // },\\n});\\n`;\n}\n\nfunction tsconfig(): string {\n return `${JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"NodeNext\",\n moduleResolution: \"NodeNext\",\n strict: true,\n skipLibCheck: true,\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction packageJson(name: string): string {\n return `${JSON.stringify(\n {\n name,\n private: true,\n type: \"module\",\n scripts: {\n dev: \"silica dev\",\n build: \"silica build\",\n start: \"silica start\",\n },\n dependencies: {\n ...scaffoldDependencyRanges,\n next: \"^16.2.6\",\n react: \"^19.2.6\",\n \"react-dom\": \"^19.2.6\",\n },\n devDependencies: {\n \"@tailwindcss/postcss\": \"^4.1.18\",\n \"@types/node\": \"^25.9.1\",\n \"@types/react\": \"^19.2.10\",\n \"@types/react-dom\": \"^19.2.3\",\n tailwindcss: \"^4.1.18\",\n typescript: \"^6.0.3\",\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction envExample(): string {\n return `BETTER_AUTH_SECRET=\\nBETTER_AUTH_URL=http://localhost:3000\\nGOOGLE_CLIENT_ID=\\nGOOGLE_CLIENT_SECRET=\\nSILICA_ASSISTANT_SECRET=\\n`;\n}\n\nfunction gitignore(): string {\n return `.silica/\\nnode_modules/\\n.env\\n.env.*\\n!.env.example\\n`;\n}\n\nfunction dockerignore(): string {\n return `.git\\n.silica\\nnode_modules\\n.env\\n.env.*\\n!.env.example\\n`;\n}\n\nfunction readme(name: string): string {\n return `# ${name}\\n\\nA Silica vault.\\n\\n## Commands\\n\\n- \\`npm run dev\\` — materialize and run the hidden Next.js app.\\n- \\`npm run build\\` — precompute content and build for production.\\n- \\`npm run start\\` — serve the production build.\\n\\n## Rendering\\n\\nSilica prerenders all notes by default and caches every rendered note. Large vaults can reduce build work in \\`silica.config.ts\\`:\\n\\n\\`\\`\\`ts\\nexport default defineConfig({\\n render: {\\n prerender: { depth: 2 },\\n },\\n});\\n\\`\\`\\`\\n\\nUse \\`prerender: \\\"none\\\"\\` for fully on-demand rendering, or \\`strategy: \\\"custom\\\"\\` with \\`include\\`, \\`exclude\\`, and \\`limit\\` for hot-page selection.\\n\\n## Auth\\n\\nCopy \\`.env.example\\` to \\`.env\\` and fill in Better Auth / Google OAuth values before enabling \\`auth\\` in \\`silica.config.ts\\`. Auth requires at least one \\`allowedDomains\\` or \\`allowedEmails\\` entry and a strong \\`BETTER_AUTH_SECRET\\` in production.\\n\\n## Docker\\n\\nThe scaffolded Dockerfile builds the generated standalone Next.js output and starts the traced \\`server.js\\` from wherever Next places it inside the standalone tree. Mount \\`/app/data/cache/next\\` as a volume to preserve rendered-note cache entries across container replacement.\\n`;\n}\n\nfunction dockerfile(): string {\n return `FROM node:22-alpine AS deps\\nWORKDIR /app\\nCOPY package*.json ./\\nRUN npm ci\\n\\nFROM deps AS build\\nCOPY . .\\nRUN npm run build\\n\\nFROM node:22-alpine AS runner\\nWORKDIR /app\\nENV NODE_ENV=production\\nENV SILICA_CACHE_DIR=/app/data/cache/next\\nCOPY --from=build /app/.silica/next/.next/standalone ./\\nCOPY --from=build /app/.silica/next/.next/static ./.silica-standalone-assets/.next/static\\nCOPY --from=build /app/.silica/next/public ./.silica-standalone-assets/public\\nCOPY --from=build /app/.silica/next/data ./.silica-standalone-assets/data\\nRUN set -eux; \\\\\\n server_file=\"$(find . -path '*/server.js' -print -quit)\"; \\\\\\n test -n \"$server_file\"; \\\\\\n server_dir=\"$(dirname \"$server_file\")\"; \\\\\\n rm -rf \"$server_dir/.next/static\" \"$server_dir/public\" \"$server_dir/data\"; \\\\\\n mkdir -p \"$server_dir/.next\"; \\\\\\n cp -R .silica-standalone-assets/.next/static \"$server_dir/.next/static\"; \\\\\\n cp -R .silica-standalone-assets/public \"$server_dir/public\"; \\\\\\n cp -R .silica-standalone-assets/data \"$server_dir/data\"; \\\\\\n rm -rf .silica-standalone-assets\\nEXPOSE 3000\\nCMD [\"sh\", \"-c\", \"node $(find . -path '*/server.js' -print -quit)\"]\\n`;\n}\n\nfunction workflow(): string {\n return `name: Build Silica image\\n\\non:\\n push:\\n branches: [main]\\n\\njobs:\\n image:\\n runs-on: ubuntu-latest\\n permissions:\\n contents: read\\n packages: write\\n steps:\\n - uses: actions/checkout@v5\\n - uses: docker/login-action@v4\\n with:\\n registry: ghcr.io\\n username: \\${{ github.actor }}\\n password: \\${{ secrets.GITHUB_TOKEN }}\\n - uses: docker/build-push-action@v7\\n with:\\n context: .\\n push: true\\n tags: ghcr.io/\\${{ github.repository }}:latest\\n # Optional SSH deploy:\\n # - name: Deploy on remote host\\n # if: \\${{ secrets.SSH_HOST != '' }}\\n # uses: appleboy/ssh-action@v1.2.0\\n # with:\\n # host: \\${{ secrets.SSH_HOST }}\\n # username: \\${{ secrets.SSH_USER }}\\n # key: \\${{ secrets.SSH_KEY }}\\n # script: |\\n # docker pull ghcr.io/\\${{ github.repository }}:latest\\n # docker stop silica || true\\n # docker rm silica || true\\n # docker run -d --name silica -p 3000:3000 ghcr.io/\\${{ github.repository }}:latest\\n`;\n}\n","// This file is generated by scripts/sync-scaffold-versions.mjs.\n// Run npm run scaffold-versions:update after package version changes.\n\nexport const scaffoldDependencyRanges = {\n \"@silicajs/cli\": \"^0.4.0\",\n \"@silicajs/core\": \"^0.9.0\",\n \"@silicajs/next\": \"^0.6.0\",\n \"@silicajs/theme-amethyst\": \"^0.5.1\",\n} as const;\n","import path from \"node:path\";\nimport { watch } from \"chokidar\";\nimport fs from \"fs-extra\";\nimport Database from \"better-sqlite3\";\nimport { precompute } from \"@silicajs/core\";\n\nexport type WatchOptions = {\n projectRoot: string;\n port?: number;\n onConfigChange?: () => void | Promise<void>;\n};\n\nexport function resolveWatchPaths(projectRoot: string): string[] {\n return [\n path.join(projectRoot, \"content\"),\n path.join(projectRoot, \"themes\"),\n path.join(projectRoot, \"silica.config.ts\"),\n ];\n}\n\nexport function watchContent({\n projectRoot,\n port = 3000,\n onConfigChange,\n}: WatchOptions) {\n const watcher = watch(resolveWatchPaths(projectRoot), {\n ignoreInitial: true,\n });\n\n let pending: Promise<void> | undefined;\n watcher.on(\"all\", (_event, filePath) => {\n pending ??= Promise.resolve()\n .then(async () => {\n if (requiresRestart(filePath, projectRoot)) {\n await onConfigChange?.();\n return;\n }\n const previous = await readRenderHashes(projectRoot);\n await precompute({ projectRoot });\n const current = await readRenderHashes(projectRoot);\n const changedSlugs = getChangedSlugs(previous, current);\n for (const slug of changedSlugs) {\n const response = await fetch(\n `http://localhost:${port}/api/silica/revalidate?tag=${encodeURIComponent(\n `page:${slug}`,\n )}`,\n {\n method: \"POST\",\n headers: {\n \"x-silica-revalidate-secret\":\n process.env.SILICA_REVALIDATE_SECRET ?? \"\",\n },\n },\n ).catch(() => undefined);\n if (!response?.ok) {\n const detail = response\n ? `${response.status} ${response.statusText}`\n : \"network error\";\n console.warn(`[silica] revalidate failed (${detail})`);\n }\n }\n console.log(`[silica] rebuilt content after ${filePath}`);\n })\n .finally(() => {\n pending = undefined;\n });\n });\n\n return watcher;\n}\n\nasync function readRenderHashes(\n projectRoot: string,\n): Promise<Map<string, string>> {\n const databasePath = path.join(projectRoot, \".silica/next/data/vault.db\");\n if (!(await fs.pathExists(databasePath))) return new Map();\n const db = new Database(databasePath, {\n fileMustExist: true,\n readonly: true,\n });\n try {\n db.pragma(\"query_only = ON\");\n const rows = db\n .prepare(\"SELECT slug, render_hash FROM notes\")\n .all() as Array<{ slug: string; render_hash: string }>;\n return new Map(rows.map((row) => [row.slug, row.render_hash]));\n } finally {\n db.close();\n }\n}\n\nfunction getChangedSlugs(\n previous: Map<string, string>,\n current: Map<string, string>,\n): string[] {\n const changed: string[] = [];\n for (const [slug, renderHash] of current) {\n if (previous.get(slug) !== renderHash) changed.push(slug);\n }\n for (const slug of previous.keys()) {\n if (!current.has(slug)) changed.push(slug);\n }\n return changed;\n}\n\nexport function requiresRestart(\n filePath: string,\n projectRoot?: string,\n): boolean {\n const normalized =\n path.isAbsolute(filePath) && projectRoot\n ? path.relative(projectRoot, filePath).replace(/\\\\/g, \"/\")\n : filePath.replace(/\\\\/g, \"/\");\n return normalized === \"silica.config.ts\" || normalized.startsWith(\"themes/\");\n}\n\nexport function resolveDevPort(env: NodeJS.ProcessEnv = process.env): number {\n const parsed = Number(env.PORT);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : 3000;\n}\n"],"mappings":"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","names":["precompute","require","path","execa","fs","loadConfig","path","fs","path","fs","path","fs","precompute"]}
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silicajs/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Silica command-line interface.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,9 +26,10 @@
|
|
|
26
26
|
"lint": "tsc --noEmit"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@
|
|
30
|
-
"@silicajs/
|
|
31
|
-
"
|
|
29
|
+
"@next/env": "^16.2.7",
|
|
30
|
+
"@silicajs/core": "^0.9.0",
|
|
31
|
+
"@silicajs/next": "^0.6.0",
|
|
32
|
+
"better-sqlite3": "^12.11.1",
|
|
32
33
|
"chokidar": "^5.0.0",
|
|
33
34
|
"commander": "^15.0.0",
|
|
34
35
|
"execa": "^9.6.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands.ts","../src/diagnostics.ts","../src/materialize.ts","../src/next.ts","../src/scaffold.ts","../src/scaffold-versions.ts","../src/watch.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport {\n buildCommand,\n createCommand,\n devCommand,\n startCommand,\n} from \"./commands.js\";\n\nexport {\n buildCommand,\n createCommand,\n devCommand,\n startCommand,\n} from \"./commands.js\";\n\nexport async function main(argv = process.argv): Promise<void> {\n const program = new Command();\n program\n .name(\"silica\")\n .description(\"Publish an Obsidian-flavored markdown vault with Next.js.\")\n .version(\"0.1.0\");\n\n program\n .command(\"create\")\n .argument(\"<directory>\", \"directory to create\")\n .description(\"scaffold a new Silica vault\")\n .action(async (directory: string) => {\n await createCommand(directory);\n });\n\n program\n .command(\"dev\")\n .description(\"materialize the hidden Next.js app and start development\")\n .action(async () => {\n await devCommand();\n });\n\n program\n .command(\"build\")\n .description(\"precompute content and build the hidden Next.js app\")\n .action(async () => {\n await buildCommand();\n });\n\n program\n .command(\"start\")\n .description(\"start the built hidden Next.js app\")\n .action(async () => {\n await startCommand();\n });\n\n await program.parseAsync(argv);\n}\n","import crypto from \"node:crypto\";\nimport { precompute } from \"@silicajs/core\";\nimport { reportBrokenWikilinks } from \"./diagnostics.js\";\nimport { materializeNextApp } from \"./materialize.js\";\nimport { runNext, runStart, startNext } from \"./next.js\";\nimport { scaffoldProject } from \"./scaffold.js\";\nimport { resolveDevPort, watchContent } from \"./watch.js\";\n\nexport async function createCommand(directory: string): Promise<void> {\n await scaffoldProject(directory);\n console.log(`[silica] created ${directory}`);\n}\n\nexport async function devCommand(): Promise<void> {\n const projectRoot = process.cwd();\n let shouldRestart = true;\n\n while (shouldRestart) {\n shouldRestart = false;\n process.env.SILICA_REVALIDATE_SECRET ??= crypto.randomUUID();\n const nextRoot = await materializeNextApp({ projectRoot });\n await precompute({ projectRoot });\n const { subprocess } = await startNext(\"dev\", nextRoot);\n const watcher = watchContent({\n projectRoot,\n port: resolveDevPort(),\n onConfigChange: async () => {\n console.log(\"[silica] config or theme changed; restarting Next.js\");\n shouldRestart = true;\n subprocess.kill(\"SIGTERM\");\n },\n });\n\n try {\n await subprocess;\n } catch (error) {\n if (!shouldRestart) throw error;\n } finally {\n await watcher.close();\n }\n }\n}\n\nexport async function buildCommand(): Promise<void> {\n const projectRoot = process.cwd();\n const nextRoot = await materializeNextApp({ projectRoot });\n const result = await precompute({ projectRoot });\n reportBrokenWikilinks(result.brokenLinks);\n await runNext(\"build\", nextRoot);\n}\n\nexport async function startCommand(): Promise<void> {\n const nextRoot = await materializeNextApp({ projectRoot: process.cwd() });\n await runStart(nextRoot);\n}\n","export type BrokenLinkDiagnostic = {\n source: string;\n target: string;\n};\n\nexport function formatBrokenWikilinks(links: BrokenLinkDiagnostic[]): string {\n if (links.length === 0) return \"\";\n return [\n \"[silica] broken wikilinks:\",\n ...links\n .slice()\n .sort((a, b) =>\n `${a.source}\\0${a.target}`.localeCompare(`${b.source}\\0${b.target}`),\n )\n .map((link) => ` ${link.source} -> ${link.target}`),\n ].join(\"\\n\");\n}\n\nexport function reportBrokenWikilinks(links: BrokenLinkDiagnostic[]): void {\n const message = formatBrokenWikilinks(links);\n if (message) console.warn(message);\n}\n","import path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport fs from \"fs-extra\";\nimport { loadConfig } from \"@silicajs/core\";\nimport {\n assistantModuleTemplate,\n assistantRouteTemplate,\n getSilicaTemplates,\n nextConfigTemplate,\n packageJsonTemplate,\n proxyTemplate,\n themeModuleTemplate,\n tsconfigTemplate,\n} from \"@silicajs/next\";\n\nexport type MaterializeOptions = {\n projectRoot?: string;\n};\n\nexport async function materializeNextApp(\n options: MaterializeOptions = {},\n): Promise<string> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const nextRoot = path.join(projectRoot, \".silica/next\");\n const publicRoot = path.join(nextRoot, \"public\");\n const config = await loadConfig(projectRoot);\n const configImport = await resolveUserConfigImport(projectRoot, nextRoot);\n\n await fs.ensureDir(nextRoot);\n await fs.remove(path.join(nextRoot, \"app\"));\n await fs.ensureDir(publicRoot);\n\n for (const template of getSilicaTemplates()) {\n const destination = path.join(nextRoot, template.path);\n await fs.ensureDir(path.dirname(destination));\n await fs.writeFile(destination, template.content);\n }\n\n await fs.writeFile(\n path.join(nextRoot, \"next.config.ts\"),\n nextConfigTemplate(configImport),\n );\n await fs.writeFile(path.join(nextRoot, \"proxy.ts\"), proxyTemplate(config));\n await fs.writeFile(\n path.join(nextRoot, \"silica-theme.ts\"),\n themeModuleTemplate(config.theme),\n );\n await fs.writeFile(\n path.join(nextRoot, \"silica-assistant.ts\"),\n assistantModuleTemplate(Boolean(config.assistant)),\n );\n if (config.assistant) {\n assertAssistantDependenciesInstalled(\n projectRoot,\n config.assistant.provider,\n );\n const assistantRoutePath = path.join(\n nextRoot,\n \"app/api/assistant/route.ts\",\n );\n await fs.ensureDir(path.dirname(assistantRoutePath));\n await fs.writeFile(\n assistantRoutePath,\n assistantRouteTemplate(config.assistant),\n );\n }\n await fs.writeFile(\n path.join(nextRoot, \"package.json\"),\n packageJsonTemplate(),\n );\n await fs.writeFile(\n path.join(nextRoot, \"tsconfig.json\"),\n `${tsconfigTemplate(await fs.pathExists(path.join(projectRoot, \"tsconfig.json\")))}\\n`,\n );\n await fs.writeFile(\n path.join(nextRoot, \"next-env.d.ts\"),\n '/// <reference types=\"next\" />\\n/// <reference types=\"next/image-types/global\" />\\n',\n );\n await syncEnvFiles(projectRoot, nextRoot);\n await overlayPublic(projectRoot, publicRoot);\n return nextRoot;\n}\n\nfunction assertAssistantDependenciesInstalled(\n projectRoot: string,\n provider: { package: string },\n): void {\n if (!isPackageInstalled(projectRoot, \"@silicajs/assistant\")) {\n throw new Error(\n \"Assistant is enabled in silica.config.ts but @silicajs/assistant is not installed.\\n\" +\n \"Install it together with the provider package for your configured model, e.g.:\\n\" +\n \" npm install @silicajs/assistant @core-ai/openai\",\n );\n }\n\n if (!isPackageInstalled(projectRoot, provider.package)) {\n throw new Error(\n `Assistant is enabled in silica.config.ts but ${provider.package} is not installed.\\n` +\n \"Install it together with @silicajs/assistant for your configured model, e.g.:\\n\" +\n ` npm install @silicajs/assistant ${provider.package}`,\n );\n }\n}\n\nfunction isPackageInstalled(projectRoot: string, packageName: string): boolean {\n const require = createRequire(path.join(projectRoot, \"package.json\"));\n for (const searchPath of require.resolve.paths(packageName) ?? []) {\n if (fs.existsSync(path.join(searchPath, packageName, \"package.json\"))) {\n return true;\n }\n }\n return false;\n}\n\nasync function resolveUserConfigImport(\n projectRoot: string,\n nextRoot: string,\n): Promise<string | undefined> {\n const configPath = await findUserConfig(projectRoot);\n if (!configPath) return undefined;\n\n const relativePath = path\n .relative(nextRoot, configPath)\n .split(path.sep)\n .join(\"/\");\n return relativePath.startsWith(\".\") ? relativePath : `./${relativePath}`;\n}\n\nasync function findUserConfig(\n projectRoot: string,\n): Promise<string | undefined> {\n for (const filename of [\"silica.config.ts\", \"silica.config.js\"]) {\n const configPath = path.join(projectRoot, filename);\n if (await fs.pathExists(configPath)) return configPath;\n }\n return undefined;\n}\n\nasync function syncEnvFiles(\n projectRoot: string,\n nextRoot: string,\n): Promise<void> {\n const entries = await fs.readdir(projectRoot).catch(() => []);\n for (const entry of entries.filter(\n (name) => name === \".env\" || name.startsWith(\".env.\"),\n )) {\n const source = path.join(projectRoot, entry);\n const destination = path.join(nextRoot, entry);\n await fs.remove(destination);\n try {\n await fs.symlink(source, destination);\n } catch {\n await fs.copyFile(source, destination);\n }\n }\n}\n\nasync function overlayPublic(\n projectRoot: string,\n publicRoot: string,\n): Promise<void> {\n const sourceRoot = path.join(projectRoot, \"public\");\n if (!(await fs.pathExists(sourceRoot))) return;\n await fs.ensureDir(publicRoot);\n for (const entry of await fs.readdir(sourceRoot)) {\n if (entry === \"silica\") continue;\n const source = path.join(sourceRoot, entry);\n const destination = path.join(publicRoot, entry);\n await fs.remove(destination);\n try {\n await fs.symlink(\n source,\n destination,\n (await fs.stat(source)).isDirectory() ? \"dir\" : \"file\",\n );\n } catch {\n await fs.copy(source, destination);\n }\n }\n}\n","import path from \"node:path\";\nimport { execa, type ResultPromise } from \"execa\";\nimport fs from \"fs-extra\";\nimport { loadConfig } from \"@silicajs/core\";\n\nexport type NextCommand = \"dev\" | \"build\" | \"start\";\nexport type NextSubprocess = {\n subprocess: ResultPromise;\n};\n\nexport async function runNext(\n command: NextCommand,\n nextRoot: string,\n): Promise<void> {\n const { subprocess } = await startNext(command, nextRoot);\n await subprocess;\n}\n\nexport async function runStart(nextRoot: string): Promise<void> {\n const standaloneServer = await findStandaloneServer(nextRoot);\n if (!standaloneServer) {\n await runNext(\"start\", nextRoot);\n return;\n }\n\n await prepareStandaloneAssets(nextRoot, standaloneServer);\n installStackTraceRewrite(nextRoot);\n const subprocess = execa(\"node\", [standaloneServer], {\n stdin: \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n cwd: path.dirname(standaloneServer),\n env: await makeNextEnv(),\n });\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => {\n process.stdout.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n subprocess.stderr?.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n await subprocess;\n}\n\nexport async function startNext(\n command: NextCommand,\n nextRoot: string,\n): Promise<NextSubprocess> {\n installStackTraceRewrite(nextRoot);\n const subprocess = execa(\"next\", [command, nextRoot], {\n stdin: \"inherit\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n env: await makeNextEnv(),\n });\n\n subprocess.stdout?.on(\"data\", (chunk: Buffer) => {\n process.stdout.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n subprocess.stderr?.on(\"data\", (chunk: Buffer) => {\n process.stderr.write(rewriteFrameworkPaths(chunk.toString(), nextRoot));\n });\n\n return { subprocess };\n}\n\nexport async function findStandaloneServer(\n nextRoot: string,\n): Promise<string | undefined> {\n const standaloneRoot = path.join(nextRoot, \".next/standalone\");\n if (!(await fs.pathExists(standaloneRoot))) return undefined;\n return findFile(standaloneRoot, \"server.js\");\n}\n\nexport async function prepareStandaloneAssets(\n nextRoot: string,\n standaloneServer: string,\n): Promise<void> {\n const serverRoot = path.dirname(standaloneServer);\n await syncStandaloneAsset(\n path.join(nextRoot, \".next/static\"),\n path.join(serverRoot, \".next/static\"),\n );\n await syncStandaloneAsset(\n path.join(nextRoot, \"public\"),\n path.join(serverRoot, \"public\"),\n );\n}\n\nexport function installStackTraceRewrite(nextRoot: string): void {\n const previous = Error.prepareStackTrace;\n Error.prepareStackTrace = (error, stack) => {\n const rendered = previous\n ? previous(error, stack)\n : `${error.name}: ${error.message}\\n${stack.join(\"\\n\")}`;\n return rewriteFrameworkPaths(String(rendered), nextRoot);\n };\n}\n\nexport function rewriteFrameworkPaths(\n output: string,\n nextRoot: string,\n): string {\n const normalizedRoot = nextRoot.replace(/\\\\/g, \"/\");\n const escapedWindowsRoot = normalizedRoot.replace(/\\//g, \"\\\\\");\n return output\n .replaceAll(`${normalizedRoot}/app/`, \"@silicajs/next [route]/\")\n .replaceAll(`${escapedWindowsRoot}\\\\app\\\\`, \"@silicajs/next [route]\\\\\")\n .replaceAll(`${normalizedRoot}/`, \".silica/next/\")\n .replaceAll(`${escapedWindowsRoot}\\\\`, \".silica\\\\next\\\\\");\n}\n\nasync function makeNextEnv(): Promise<NodeJS.ProcessEnv> {\n const config = await loadConfig(process.cwd());\n const authEnabled =\n Boolean(config.auth) || process.env.SILICA_AUTH_ENABLED === \"true\";\n const allowedDomains = uniqueList([\n ...(config.auth?.allowedDomains ?? []),\n ...parseList(process.env.SILICA_ALLOWED_DOMAINS),\n ]);\n const allowedEmails = uniqueList([\n ...(config.auth?.allowedEmails ?? []),\n ...parseList(process.env.SILICA_ALLOWED_EMAILS),\n ]);\n\n return {\n ...process.env,\n SILICA_PROJECT_ROOT: process.cwd(),\n SILICA_AUTH_ENABLED: authEnabled ? \"true\" : \"false\",\n SILICA_ALLOWED_DOMAINS: allowedDomains.join(\",\"),\n SILICA_ALLOWED_EMAILS: allowedEmails.join(\",\"),\n };\n}\n\nfunction parseList(value: string | undefined): string[] {\n return value\n ? value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean)\n : [];\n}\n\nfunction uniqueList(values: readonly string[]): string[] {\n return [...new Set(values.map((item) => item.trim()).filter(Boolean))];\n}\n\nasync function syncStandaloneAsset(\n source: string,\n destination: string,\n): Promise<void> {\n if (!(await fs.pathExists(source))) return;\n if (path.resolve(source) === path.resolve(destination)) return;\n\n await fs.remove(destination);\n await fs.ensureDir(path.dirname(destination));\n try {\n await fs.symlink(source, destination, \"dir\");\n } catch {\n await fs.copy(source, destination);\n }\n}\n\nasync function findFile(\n root: string,\n filename: string,\n): Promise<string | undefined> {\n const entries = await fs.readdir(root, { withFileTypes: true });\n for (const entry of entries) {\n const absolute = path.join(root, entry.name);\n if (entry.isFile() && entry.name === filename) return absolute;\n if (entry.isDirectory()) {\n const found = await findFile(absolute, filename);\n if (found) return found;\n }\n }\n return undefined;\n}\n","import path from \"node:path\";\nimport fs from \"fs-extra\";\nimport { scaffoldDependencyRanges } from \"./scaffold-versions.js\";\n\nexport async function scaffoldProject(targetDir: string): Promise<void> {\n const root = path.resolve(targetDir);\n if ((await fs.pathExists(root)) && (await fs.readdir(root)).length > 0) {\n throw new Error(`Target directory is not empty: ${root}`);\n }\n\n await fs.ensureDir(path.join(root, \"content/notes\"));\n await fs.ensureDir(path.join(root, \".github/workflows\"));\n await fs.writeFile(path.join(root, \"content/index.md\"), indexMarkdown());\n await fs.writeFile(\n path.join(root, \"content/notes/getting-started.md\"),\n gettingStartedMarkdown(),\n );\n await fs.writeFile(path.join(root, \"silica.config.ts\"), silicaConfig());\n await fs.writeFile(path.join(root, \"tsconfig.json\"), tsconfig());\n await fs.writeFile(\n path.join(root, \"package.json\"),\n packageJson(path.basename(root)),\n );\n await fs.writeFile(path.join(root, \".env.example\"), envExample());\n await fs.writeFile(path.join(root, \".gitignore\"), gitignore());\n await fs.writeFile(path.join(root, \".dockerignore\"), dockerignore());\n await fs.writeFile(path.join(root, \"README.md\"), readme(path.basename(root)));\n await fs.writeFile(path.join(root, \"Dockerfile\"), dockerfile());\n await fs.writeFile(\n path.join(root, \".github/workflows/deploy.yml\"),\n workflow(),\n );\n}\n\nfunction indexMarkdown(): string {\n return `---\\ntitle: Welcome\\ntags: [home]\\n---\\n\\n# Welcome\\n\\nThis is your new Silica vault. Open [[notes/getting-started|Getting started]] to learn the basics.\\n\\n> [!note] Edit freely\\n> Write standard Markdown plus Obsidian-style wikilinks.\\n`;\n}\n\nfunction gettingStartedMarkdown(): string {\n return `---\\ntitle: Getting started\\ntags: [guide]\\n---\\n\\n# Getting started\\n\\nRun \\`npm run dev\\` and edit files in \\`content/\\`. Silica regenerates the hidden Next.js app under \\`.silica/\\`.\\n`;\n}\n\nfunction silicaConfig(): string {\n return `import { defineConfig } from \"@silicajs/core\";\\n\\nexport default defineConfig({\\n title: \"My Silica Site\",\\n description: \"A private knowledge site\",\\n theme: \"default\",\\n // auth: {\\n // provider: \"google\",\\n // allowedDomains: [\"example.com\"],\\n // },\\n});\\n`;\n}\n\nfunction tsconfig(): string {\n return `${JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"NodeNext\",\n moduleResolution: \"NodeNext\",\n strict: true,\n skipLibCheck: true,\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction packageJson(name: string): string {\n return `${JSON.stringify(\n {\n name,\n private: true,\n type: \"module\",\n scripts: {\n dev: \"silica dev\",\n build: \"silica build\",\n start: \"silica start\",\n },\n dependencies: {\n ...scaffoldDependencyRanges,\n next: \"^16.2.6\",\n react: \"^19.2.6\",\n \"react-dom\": \"^19.2.6\",\n },\n devDependencies: {\n \"@tailwindcss/postcss\": \"^4.1.18\",\n \"@types/node\": \"^25.9.1\",\n \"@types/react\": \"^19.2.10\",\n \"@types/react-dom\": \"^19.2.3\",\n tailwindcss: \"^4.1.18\",\n typescript: \"^6.0.3\",\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction envExample(): string {\n return `BETTER_AUTH_SECRET=\\nBETTER_AUTH_URL=http://localhost:3000\\nGOOGLE_CLIENT_ID=\\nGOOGLE_CLIENT_SECRET=\\nSILICA_ASSISTANT_SECRET=\\n`;\n}\n\nfunction gitignore(): string {\n return `.silica/\\nnode_modules/\\n.env\\n.env.*\\n!.env.example\\n`;\n}\n\nfunction dockerignore(): string {\n return `.git\\n.silica\\nnode_modules\\n.env\\n.env.*\\n!.env.example\\n`;\n}\n\nfunction readme(name: string): string {\n return `# ${name}\\n\\nA Silica vault.\\n\\n## Commands\\n\\n- \\`npm run dev\\` — materialize and run the hidden Next.js app.\\n- \\`npm run build\\` — precompute content and build for production.\\n- \\`npm run start\\` — serve the production build.\\n\\n## Rendering\\n\\nSilica prerenders all notes by default and caches every rendered note. Large vaults can reduce build work in \\`silica.config.ts\\`:\\n\\n\\`\\`\\`ts\\nexport default defineConfig({\\n render: {\\n prerender: { depth: 2 },\\n },\\n});\\n\\`\\`\\`\\n\\nUse \\`prerender: \\\"none\\\"\\` for fully on-demand rendering, or \\`strategy: \\\"custom\\\"\\` with \\`include\\`, \\`exclude\\`, and \\`limit\\` for hot-page selection.\\n\\n## Auth\\n\\nCopy \\`.env.example\\` to \\`.env\\` and fill in Better Auth / Google OAuth values before enabling \\`auth\\` in \\`silica.config.ts\\`. Auth requires at least one \\`allowedDomains\\` or \\`allowedEmails\\` entry and a strong \\`BETTER_AUTH_SECRET\\` in production.\\n\\n## Docker\\n\\nThe scaffolded Dockerfile builds the generated standalone Next.js output and starts the traced \\`server.js\\` from wherever Next places it inside the standalone tree. Mount \\`/app/.silica/cache/next\\` as a volume to preserve rendered-note cache entries across container replacement.\\n`;\n}\n\nfunction dockerfile(): string {\n return `FROM node:22-alpine AS deps\\nWORKDIR /app\\nCOPY package*.json ./\\nRUN npm ci\\n\\nFROM deps AS build\\nCOPY . .\\nRUN npm run build\\n\\nFROM node:22-alpine AS runner\\nWORKDIR /app\\nENV NODE_ENV=production\\nENV SILICA_PROJECT_ROOT=/app\\nENV SILICA_CACHE_DIR=/app/.silica/cache/next\\nCOPY --from=build /app/.silica/next/.next/standalone ./\\nCOPY --from=build /app/.silica/next/.next/static ./.silica/next/.next/static\\nCOPY --from=build /app/.silica/next/public ./.silica/next/public\\nCOPY --from=build /app/.silica ./.silica\\nEXPOSE 3000\\nCMD [\"sh\", \"-c\", \"node $(find . -path '*/server.js' -print -quit)\"]\\n`;\n}\n\nfunction workflow(): string {\n return `name: Build Silica image\\n\\non:\\n push:\\n branches: [main]\\n\\njobs:\\n image:\\n runs-on: ubuntu-latest\\n permissions:\\n contents: read\\n packages: write\\n steps:\\n - uses: actions/checkout@v5\\n - uses: docker/login-action@v4\\n with:\\n registry: ghcr.io\\n username: \\${{ github.actor }}\\n password: \\${{ secrets.GITHUB_TOKEN }}\\n - uses: docker/build-push-action@v7\\n with:\\n context: .\\n push: true\\n tags: ghcr.io/\\${{ github.repository }}:latest\\n # Optional SSH deploy:\\n # - name: Deploy on remote host\\n # if: \\${{ secrets.SSH_HOST != '' }}\\n # uses: appleboy/ssh-action@v1.2.0\\n # with:\\n # host: \\${{ secrets.SSH_HOST }}\\n # username: \\${{ secrets.SSH_USER }}\\n # key: \\${{ secrets.SSH_KEY }}\\n # script: |\\n # docker pull ghcr.io/\\${{ github.repository }}:latest\\n # docker stop silica || true\\n # docker rm silica || true\\n # docker run -d --name silica -p 3000:3000 ghcr.io/\\${{ github.repository }}:latest\\n`;\n}\n","// This file is generated by scripts/sync-scaffold-versions.mjs.\n// Run npm run scaffold-versions:update after package version changes.\n\nexport const scaffoldDependencyRanges = {\n \"@silicajs/cli\": \"^0.3.0\",\n \"@silicajs/core\": \"^0.8.0\",\n \"@silicajs/next\": \"^0.5.0\",\n \"@silicajs/theme-amethyst\": \"^0.5.0\",\n} as const;\n","import path from \"node:path\";\nimport { watch } from \"chokidar\";\nimport fs from \"fs-extra\";\nimport Database from \"better-sqlite3\";\nimport { precompute } from \"@silicajs/core\";\n\nexport type WatchOptions = {\n projectRoot: string;\n port?: number;\n onConfigChange?: () => void | Promise<void>;\n};\n\nexport function resolveWatchPaths(projectRoot: string): string[] {\n return [\n path.join(projectRoot, \"content\"),\n path.join(projectRoot, \"themes\"),\n path.join(projectRoot, \"silica.config.ts\"),\n ];\n}\n\nexport function watchContent({\n projectRoot,\n port = 3000,\n onConfigChange,\n}: WatchOptions) {\n const watcher = watch(resolveWatchPaths(projectRoot), {\n ignoreInitial: true,\n });\n\n let pending: Promise<void> | undefined;\n watcher.on(\"all\", (_event, filePath) => {\n pending ??= Promise.resolve()\n .then(async () => {\n if (requiresRestart(filePath, projectRoot)) {\n await onConfigChange?.();\n return;\n }\n const previous = await readRenderHashes(projectRoot);\n await precompute({ projectRoot });\n const current = await readRenderHashes(projectRoot);\n const changedSlugs = getChangedSlugs(previous, current);\n for (const slug of changedSlugs) {\n const response = await fetch(\n `http://localhost:${port}/api/silica/revalidate?tag=${encodeURIComponent(\n `page:${slug}`,\n )}`,\n {\n method: \"POST\",\n headers: {\n \"x-silica-revalidate-secret\":\n process.env.SILICA_REVALIDATE_SECRET ?? \"\",\n },\n },\n ).catch(() => undefined);\n if (!response?.ok) {\n const detail = response\n ? `${response.status} ${response.statusText}`\n : \"network error\";\n console.warn(`[silica] revalidate failed (${detail})`);\n }\n }\n console.log(`[silica] rebuilt content after ${filePath}`);\n })\n .finally(() => {\n pending = undefined;\n });\n });\n\n return watcher;\n}\n\nasync function readRenderHashes(\n projectRoot: string,\n): Promise<Map<string, string>> {\n const databasePath = path.join(projectRoot, \".silica/vault.db\");\n if (!(await fs.pathExists(databasePath))) return new Map();\n const db = new Database(databasePath, {\n fileMustExist: true,\n readonly: true,\n });\n try {\n db.pragma(\"query_only = ON\");\n const rows = db\n .prepare(\"SELECT slug, render_hash FROM notes\")\n .all() as Array<{ slug: string; render_hash: string }>;\n return new Map(rows.map((row) => [row.slug, row.render_hash]));\n } finally {\n db.close();\n }\n}\n\nfunction getChangedSlugs(\n previous: Map<string, string>,\n current: Map<string, string>,\n): string[] {\n const changed: string[] = [];\n for (const [slug, renderHash] of current) {\n if (previous.get(slug) !== renderHash) changed.push(slug);\n }\n for (const slug of previous.keys()) {\n if (!current.has(slug)) changed.push(slug);\n }\n return changed;\n}\n\nexport function requiresRestart(\n filePath: string,\n projectRoot?: string,\n): boolean {\n const normalized =\n path.isAbsolute(filePath) && projectRoot\n ? path.relative(projectRoot, filePath).replace(/\\\\/g, \"/\")\n : filePath.replace(/\\\\/g, \"/\");\n return normalized === \"silica.config.ts\" || normalized.startsWith(\"themes/\");\n}\n\nexport function resolveDevPort(env: NodeJS.ProcessEnv = process.env): number {\n const parsed = Number(env.PORT);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : 3000;\n}\n"],"mappings":"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","names":["precompute","require","path","fs","loadConfig","path","fs","path","fs","path","fs","precompute"]}
|