@podosoft/podokit 0.8.0 → 0.10.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/add.d.ts +20 -0
- package/dist/add.js +121 -8
- package/dist/assemble.d.ts +4 -1
- package/dist/assemble.js +35 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +20 -4
- package/dist/inspect.d.ts +5 -0
- package/dist/inspect.js +5 -0
- package/dist/lockfile.d.ts +20 -1
- package/dist/lockfile.js +48 -6
- package/dist/remove.js +3 -2
- package/dist/templates/fullstack-nest-svelte/apps/web/src/app.css +42 -0
- package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/components/site-runtime.svelte +7 -0
- package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/server/backend-proxy.ts +3 -1
- package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/+layout.svelte +2 -2
- package/dist/templates/fullstack-nest-svelte/dot-gitignore +6 -0
- package/dist/templates/fullstack-nest-svelte/infra/k3s/ingress.yaml +10 -0
- package/dist/templates/fullstack-nest-svelte/infra/traefik/dynamic.yml +4 -0
- package/dist/templates/modules/admin-dashboard/files/apps/api/src/site-settings/site-settings.controller.ts +60 -1
- package/dist/templates/modules/admin-dashboard/files/apps/api/src/site-settings/site-settings.service.ts +3 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/hooks.server.ts +3 -1
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/account-data.server.ts +42 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/account-menu.svelte +46 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/account-page.svelte +730 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/settings/appearance-card.svelte +371 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/sidebar-user-menu.svelte +1 -1
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/site-runtime.svelte +39 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/i18n/index.ts +12 -7
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/i18n/messages.ts +90 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/server/search-indexing.ts +29 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/site/apply-theme.ts +124 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/site/themes.ts +81 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/site.svelte.ts +6 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/+layout.server.ts +17 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/account/+page.svelte +8 -680
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/settings/+page.server.ts +10 -1
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/settings/+page.svelte +30 -11
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/settings/general-settings.svelte +0 -7
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/login/+page.svelte +96 -14
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+layout.server.ts +1 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/account/+page.server.ts +4 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/account/+page.svelte +35 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/setup-2fa/+page.server.ts +11 -0
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/setup-2fa/+page.svelte +122 -0
- package/dist/templates/modules/admin-dashboard/files/tests/api/auth.api.spec.ts +106 -0
- package/dist/templates/modules/admin-dashboard/files/tests/api/site-settings.api.spec.ts +56 -0
- package/dist/templates/modules/admin-dashboard/files/tests/seed.setup.ts +10 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/account-flows.ui.spec.ts +74 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/account.ui.spec.ts +9 -2
- package/dist/templates/modules/admin-dashboard/files/tests/ui/appearance.ui.spec.ts +63 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/auth.ui.spec.ts +11 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/general-effects.ui.spec.ts +13 -5
- package/dist/templates/modules/admin-dashboard/files/tests/ui/guards.ui.spec.ts +21 -2
- package/dist/templates/modules/admin-dashboard/files/tests/ui/impersonation.ui.spec.ts +23 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/login-methods.ui.spec.ts +41 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/oidc.ui.spec.ts +12 -8
- package/dist/templates/modules/admin-dashboard/files/tests/ui/organizations.ui.spec.ts +35 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/passkey.ui.spec.ts +1 -1
- package/dist/templates/modules/admin-dashboard/files/tests/ui/settings-dialogs.ui.spec.ts +63 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/settings.ui.spec.ts +23 -7
- package/dist/templates/modules/admin-dashboard/files/tests/ui/two-factor.ui.spec.ts +137 -0
- package/dist/templates/modules/admin-dashboard/files/tests/ui/verify-email.ui.spec.ts +17 -0
- package/dist/templates/modules/admin-dashboard/module.manifest.json +1 -1
- package/dist/templates/modules/api-key-auth/files/tests/api/machine.api.spec.ts +25 -0
- package/dist/templates/modules/auth/files/apps/api/src/account/account.controller.ts +8 -0
- package/dist/templates/modules/auth/files/apps/api/src/auth/two-factor-required.guard.ts +68 -0
- package/dist/templates/modules/auth/files/apps/api/src/settings/flag-defaults.ts +5 -1
- package/dist/templates/modules/auth/module.manifest.json +10 -0
- package/dist/templates/modules/bullmq/files/tests/api/jobs.api.spec.ts +38 -0
- package/dist/templates/modules/file-upload/files/tests/api/files.api.spec.ts +31 -0
- package/dist/templates/modules/job-progress/files/tests/api/progress.api.spec.ts +22 -0
- package/dist/templates/modules/object-storage-s3/files/tests/api/storage.api.spec.ts +28 -0
- package/dist/templates/modules/rate-limit/files/tests/api/rate-limit.api.spec.ts +35 -0
- package/dist/templates/modules/redis/files/tests/api/redis.api.spec.ts +30 -0
- package/dist/templates/modules/sse/files/tests/api/events.api.spec.ts +46 -0
- package/dist/templates/todo/apps/web/src/lib/components/site-runtime.svelte +7 -0
- package/dist/templates/todo/apps/web/src/lib/server/backend-proxy.ts +3 -1
- package/dist/templates/todo/apps/web/src/routes/+layout.svelte +2 -2
- package/dist/templates/todo/dot-gitignore +6 -0
- package/dist/templates/todo/infra/k3s/ingress.yaml +10 -0
- package/dist/templates/todo/infra/traefik/dynamic.yml +4 -0
- package/dist/update.js +74 -8
- package/package.json +1 -1
- package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+layout.svelte +0 -61
package/dist/update.js
CHANGED
|
@@ -9,6 +9,7 @@ const podokit_template_engine_1 = require("@podosoft/podokit-template-engine");
|
|
|
9
9
|
const assemble_1 = require("./assemble");
|
|
10
10
|
const lockfile_1 = require("./lockfile");
|
|
11
11
|
const inspect_1 = require("./inspect");
|
|
12
|
+
const add_1 = require("./add");
|
|
12
13
|
function treeText(tree, path) {
|
|
13
14
|
const file = tree.get(path);
|
|
14
15
|
if (!file)
|
|
@@ -32,7 +33,8 @@ function planUpdate(projectRoot, templatesDir) {
|
|
|
32
33
|
templatesDir,
|
|
33
34
|
template: manifest.template,
|
|
34
35
|
answers: manifest.answers,
|
|
35
|
-
modules: manifest.modules
|
|
36
|
+
modules: manifest.modules,
|
|
37
|
+
projectRoot,
|
|
36
38
|
});
|
|
37
39
|
const changes = [];
|
|
38
40
|
const paths = new Set([...newTree.keys(), ...Object.keys(lock.files)]);
|
|
@@ -92,6 +94,40 @@ function writeFile(projectRoot, path, content) {
|
|
|
92
94
|
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(abs), { recursive: true });
|
|
93
95
|
(0, node_fs_1.writeFileSync)(abs, content);
|
|
94
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Refresh update metadata without teaching the lock that a clean 3-way merge is
|
|
99
|
+
* PodoKit's new baseline. Managed files keep the newly assembled template hash,
|
|
100
|
+
* so the user's merged lines are still recognised as edits on the next update.
|
|
101
|
+
* Files that are neither in the assembled tree nor explicitly owned stay out of
|
|
102
|
+
* the lock instead of being accidentally adopted as managed files.
|
|
103
|
+
*/
|
|
104
|
+
function updatedFilesLock(projectRoot, newTree, previous, ownedGlobs) {
|
|
105
|
+
const next = (0, lockfile_1.computeFilesLock)(projectRoot, ownedGlobs);
|
|
106
|
+
for (const [path, entry] of Object.entries(next.files)) {
|
|
107
|
+
const newText = treeText(newTree, path);
|
|
108
|
+
if (newText !== null) {
|
|
109
|
+
if (entry.tier !== "owned") {
|
|
110
|
+
entry.tier = previous.files[path]?.tier ?? entry.tier;
|
|
111
|
+
entry.outHash = (0, podokit_template_engine_1.hashContent)(newText);
|
|
112
|
+
}
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (entry.tier === "owned")
|
|
116
|
+
continue;
|
|
117
|
+
const oldEntry = previous.files[path];
|
|
118
|
+
if (oldEntry && oldEntry.tier !== "owned") {
|
|
119
|
+
// Removed upstream but kept on disk because it was edited: continue to
|
|
120
|
+
// report the removal conflict until the user deletes or ejects it.
|
|
121
|
+
entry.tier = oldEntry.tier;
|
|
122
|
+
entry.outHash = oldEntry.outHash;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
// A file created by the application is not implicitly PodoKit-managed.
|
|
126
|
+
delete next.files[path];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return next;
|
|
130
|
+
}
|
|
95
131
|
/**
|
|
96
132
|
* Apply an update to the working copy. Clean updates and additions are written,
|
|
97
133
|
* upstream removals deleted, and user-edited files 3-way merged against the old
|
|
@@ -101,13 +137,26 @@ function writeFile(projectRoot, path, content) {
|
|
|
101
137
|
*/
|
|
102
138
|
function applyUpdate(projectRoot, templatesDir, options = {}) {
|
|
103
139
|
const manifest = (0, lockfile_1.readManifest)(projectRoot);
|
|
104
|
-
|
|
140
|
+
const previousLock = (0, lockfile_1.readFilesLock)(projectRoot);
|
|
141
|
+
if (!manifest || !previousLock)
|
|
105
142
|
throw new inspect_1.NotAProjectError();
|
|
106
143
|
const plan = planUpdate(projectRoot, templatesDir);
|
|
107
|
-
const modules = manifest.modules
|
|
108
|
-
const newTree = (0, assemble_1.assembleProject)({
|
|
144
|
+
const modules = manifest.modules;
|
|
145
|
+
const newTree = (0, assemble_1.assembleProject)({
|
|
146
|
+
templatesDir,
|
|
147
|
+
template: manifest.template,
|
|
148
|
+
answers: manifest.answers,
|
|
149
|
+
modules,
|
|
150
|
+
projectRoot,
|
|
151
|
+
});
|
|
109
152
|
const oldTree = options.oldTemplatesDir
|
|
110
|
-
? (0, assemble_1.assembleProject)({
|
|
153
|
+
? (0, assemble_1.assembleProject)({
|
|
154
|
+
templatesDir: options.oldTemplatesDir,
|
|
155
|
+
template: manifest.template,
|
|
156
|
+
answers: manifest.answers,
|
|
157
|
+
modules,
|
|
158
|
+
projectRoot,
|
|
159
|
+
})
|
|
111
160
|
: null;
|
|
112
161
|
const result = { written: [], removed: [], merged: [], conflicts: [] };
|
|
113
162
|
for (const change of plan.changes) {
|
|
@@ -136,9 +185,26 @@ function applyUpdate(projectRoot, templatesDir, options = {}) {
|
|
|
136
185
|
result.merged.push(change.path);
|
|
137
186
|
}
|
|
138
187
|
}
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
|
|
188
|
+
// Keep the assembled target as the managed baseline. A merged working file
|
|
189
|
+
// intentionally remains drifted so a future update performs another 3-way
|
|
190
|
+
// merge instead of treating the user's lines as clean generated output.
|
|
191
|
+
(0, lockfile_1.writeFilesLock)(projectRoot, updatedFilesLock(projectRoot, newTree, previousLock, manifest.ownedGlobs));
|
|
192
|
+
const modulesDir = (0, node_path_1.join)(templatesDir, "modules");
|
|
193
|
+
const refreshedModules = manifest.modules.map((module) => {
|
|
194
|
+
const resolved = (0, add_1.resolveModule)(module.packageName ?? module.name, modulesDir, projectRoot);
|
|
195
|
+
return resolved?.packageName
|
|
196
|
+
? {
|
|
197
|
+
...module,
|
|
198
|
+
packageName: resolved.packageName,
|
|
199
|
+
moduleVersion: resolved.moduleVersion,
|
|
200
|
+
}
|
|
201
|
+
: module;
|
|
202
|
+
});
|
|
203
|
+
(0, lockfile_1.writeManifest)(projectRoot, {
|
|
204
|
+
...manifest,
|
|
205
|
+
modules: refreshedModules,
|
|
206
|
+
podokitVersion: (0, lockfile_1.podokitVersion)(),
|
|
207
|
+
});
|
|
142
208
|
return result;
|
|
143
209
|
}
|
|
144
210
|
/** Count actions for a one-line summary. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@podosoft/podokit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "An opinionated but extensible starter toolkit and CLI for full-stack TypeScript apps with NestJS, SvelteKit, TailwindCSS, shadcn-svelte, Docker, and k3s.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import "../app.css";
|
|
3
|
-
import { ModeWatcher } from "mode-watcher";
|
|
4
|
-
import { setI18nContext } from "$lib/i18n";
|
|
5
|
-
import { messages, resolveLocale } from "$lib/i18n/messages";
|
|
6
|
-
import { site } from "$lib/site.svelte";
|
|
7
|
-
|
|
8
|
-
let { children, data } = $props();
|
|
9
|
-
const locale = $derived(resolveLocale(data.locale));
|
|
10
|
-
setI18nContext({
|
|
11
|
-
get t() {
|
|
12
|
-
return messages[locale];
|
|
13
|
-
},
|
|
14
|
-
get locale() {
|
|
15
|
-
return locale;
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
// Seed the reactive site branding; the general-settings form patches it live.
|
|
20
|
-
$effect.pre(() => site.init(data.site));
|
|
21
|
-
// Prefer live store values (patched after a save); fall back to the server load
|
|
22
|
-
// so SSR renders the saved branding too. Empty falls back to the app.html default.
|
|
23
|
-
const branding = $derived({
|
|
24
|
-
name: site.value.name ?? data.site?.name ?? "",
|
|
25
|
-
description: site.value.description ?? data.site?.description ?? "",
|
|
26
|
-
brandColor: site.value.brandColor ?? data.site?.brandColor ?? "",
|
|
27
|
-
hasFavicon: site.value.hasFavicon || Boolean(data.site?.hasFavicon),
|
|
28
|
-
faviconVersion: site.value.faviconVersion ?? data.site?.faviconVersion ?? "",
|
|
29
|
-
});
|
|
30
|
-
// Apply the site name to the browser tab live (avoids a duplicate <title> vs
|
|
31
|
-
// the app.html default; the default project name stays as the SSR fallback).
|
|
32
|
-
$effect(() => {
|
|
33
|
-
if (branding.name) document.title = branding.name;
|
|
34
|
-
});
|
|
35
|
-
// Apply the brand color as the theme's primary accent live. Clearing it in
|
|
36
|
-
// Settings restores the stylesheet default (remove the inline override).
|
|
37
|
-
$effect(() => {
|
|
38
|
-
const root = document.documentElement;
|
|
39
|
-
if (branding.brandColor) {
|
|
40
|
-
root.style.setProperty("--primary", branding.brandColor);
|
|
41
|
-
root.style.setProperty("--sidebar-primary", branding.brandColor);
|
|
42
|
-
root.style.setProperty("--ring", branding.brandColor);
|
|
43
|
-
} else {
|
|
44
|
-
root.style.removeProperty("--primary");
|
|
45
|
-
root.style.removeProperty("--sidebar-primary");
|
|
46
|
-
root.style.removeProperty("--ring");
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
</script>
|
|
50
|
-
|
|
51
|
-
<svelte:head>
|
|
52
|
-
{#if branding.description}
|
|
53
|
-
<meta name="description" content={branding.description} />
|
|
54
|
-
{/if}
|
|
55
|
-
{#if branding.hasFavicon}
|
|
56
|
-
<link rel="icon" href={`/api/site/favicon?v=${branding.faviconVersion}`} />
|
|
57
|
-
{/if}
|
|
58
|
-
</svelte:head>
|
|
59
|
-
|
|
60
|
-
<ModeWatcher />
|
|
61
|
-
{@render children()}
|