@protobase/cli 0.19.1 → 0.19.2

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.
@@ -3,6 +3,7 @@ import { buildBundlePlugins } from "./bundle-plugins.js";
3
3
  import { buildConfigBundle } from "./config-bundle.js";
4
4
  import { protobaseVersion } from "../version/version.js";
5
5
  import { copyPackages } from "./packages/copy-packages.js";
6
+ import { buildFavicon, faviconFile } from "./favicon.js";
6
7
  import { buildTheme } from "./theme.js";
7
8
  import { shellForBuild, shellManifestFile } from "./shell.js";
8
9
  import { checkUi } from "./ui-check.js";
@@ -65,6 +66,10 @@ const buildDeployBundle = async ({ projectDir, outDir, bun, extensions = [], onW
65
66
  projectDir,
66
67
  outFile: path.join(publicDir, bundleLayout.theme)
67
68
  })) onWarning?.(warning);
69
+ await buildFavicon({
70
+ projectDir,
71
+ outFile: path.join(publicDir, faviconFile)
72
+ });
68
73
  const manifest = {
69
74
  version: 3,
70
75
  protobase: protobaseVersion,
@@ -0,0 +1,17 @@
1
+ import { adminAppDir } from "../project/admin-app.js";
2
+ import { existsSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { copyFile } from "node:fs/promises";
5
+ //#region src/build/favicon.ts
6
+ /** The project's favicon, at its root, and where a bundle's `public` folder has it: the app links it at `/protobase.favicon.svg`. */
7
+ const faviconFile = "protobase.favicon.svg";
8
+ const defaultFavicon = path.join(adminAppDir, "favicon.svg");
9
+ /** The favicon the app shows for the project in `projectDir`: its protobase.favicon.svg, or Protobase's without one. */
10
+ const projectFavicon = (projectDir) => {
11
+ const own = projectDir === void 0 ? void 0 : path.join(projectDir, faviconFile);
12
+ return own && existsSync(own) ? own : defaultFavicon;
13
+ };
14
+ /** Writes the project's favicon, or Protobase's when it has none, to `outFile`, so the app's link to it always resolves. */
15
+ const buildFavicon = ({ projectDir, outFile }) => copyFile(projectFavicon(projectDir), outFile);
16
+ //#endregion
17
+ export { buildFavicon, faviconFile, projectFavicon };
@@ -2,6 +2,7 @@ import { projectUiPlugin } from "../project/project-ui.js";
2
2
  import { readPackageJson } from "./packages/package-dir.js";
3
3
  import { adminAppDir, uiEntry, uiPackageDir } from "../project/admin-app.js";
4
4
  import { sharedModulesPlugin } from "../project/shared-modules.js";
5
+ import { faviconLink } from "../project/favicon-link.js";
5
6
  import { themeLink } from "../project/theme-link.js";
6
7
  import { existsSync } from "node:fs";
7
8
  import path from "node:path";
@@ -30,7 +31,7 @@ const shellIdentity = async () => {
30
31
  * The admin app as a production build, the same for every project: index.html and content-hashed files under assets/,
31
32
  * with protobase.shell.json saying which version it is. Asset URLs are absolute, so index.html works as the answer to
32
33
  * any deep link. It calls /api on its own origin and loads the project's UI, like every plugin, from what `/meta`
33
- * names, and links the project's theme at /protobase.theme.css. The modules plugins share with it have entries of
34
+ * names, and links the project's theme at /protobase.theme.css and its favicon at /protobase.favicon.svg. The modules plugins share with it have entries of
34
35
  * their own, which index.html's import map names.
35
36
  */
36
37
  const buildShell = async (outDir) => {
@@ -47,6 +48,7 @@ const buildShell = async (outDir) => {
47
48
  sharedModulesPlugin(),
48
49
  projectUiPlugin(void 0),
49
50
  themeLink(),
51
+ faviconLink(),
50
52
  react(),
51
53
  tailwindcss()
52
54
  ],
package/dist/dev/run.js CHANGED
@@ -5,6 +5,7 @@ import { extensionImports, extensionStyles } from "../project/extensions.js";
5
5
  import { sharedModulesPlugin } from "../project/shared-modules.js";
6
6
  import { moduleFile } from "../module-file.js";
7
7
  import { layoutCheck } from "../build/layout-check.js";
8
+ import { faviconLink } from "../project/favicon-link.js";
8
9
  import { themeLink } from "../project/theme-link.js";
9
10
  import { checkDatabase } from "./check-database.js";
10
11
  import { stopDevJobs } from "./dev-jobs.js";
@@ -78,6 +79,7 @@ const runDev = async (options, out) => {
78
79
  stopJobsOnClose,
79
80
  sharedModulesPlugin(),
80
81
  themeLink(options.projectDir),
82
+ faviconLink(options.projectDir),
81
83
  projectUiPlugin(options.projectDir, extensions),
82
84
  extensionImports(options.projectDir, extensions),
83
85
  extensionStyles(extensions),
package/dist/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.19.1";
2
+ var version = "0.19.2";
3
3
  //#endregion
4
4
  export { version };
@@ -0,0 +1,39 @@
1
+ import { faviconFile, projectFavicon } from "../build/favicon.js";
2
+ import { readFile } from "node:fs/promises";
3
+ //#region src/project/favicon-link.ts
4
+ /**
5
+ * Links the project's favicon at `/protobase.favicon.svg` in the app's page. A bundle always has the file (see
6
+ * `buildFavicon`); the dev server answers it from the project's protobase.favicon.svg, or Protobase's without one.
7
+ */
8
+ const faviconLink = (projectDir) => {
9
+ let base = "/";
10
+ return {
11
+ name: "protobase-favicon-link",
12
+ configResolved: (config) => {
13
+ base = config.base;
14
+ },
15
+ configureServer: (server) => {
16
+ server.middlewares.use(`/${faviconFile}`, (_request, response, next) => {
17
+ readFile(projectFavicon(projectDir)).then((body) => {
18
+ response.setHeader("content-type", "image/svg+xml");
19
+ response.setHeader("cache-control", "no-cache");
20
+ response.end(body);
21
+ }, next);
22
+ });
23
+ },
24
+ transformIndexHtml: {
25
+ order: "post",
26
+ handler: () => [{
27
+ tag: "link",
28
+ attrs: {
29
+ rel: "icon",
30
+ type: "image/svg+xml",
31
+ href: `${base}${faviconFile}`
32
+ },
33
+ injectTo: "head"
34
+ }]
35
+ }
36
+ };
37
+ };
38
+ //#endregion
39
+ export { faviconLink };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@protobase/cli",
3
- "version": "0.19.1",
3
+ "version": "0.19.2",
4
4
  "description": "The protobase command: scaffold, doctor, dev, build and serve a Protobase project.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -34,11 +34,11 @@
34
34
  "dependencies": {
35
35
  "@hono/node-server": "^2.1.3",
36
36
  "@hono/vite-dev-server": "^0.26.1",
37
- "@protobase/layout": "0.19.1",
38
- "@protobase/query": "0.19.1",
39
- "@protobase/schema": "0.19.1",
40
- "@protobase/server": "0.19.1",
41
- "@protobase/ui": "0.19.1",
37
+ "@protobase/layout": "0.19.2",
38
+ "@protobase/query": "0.19.2",
39
+ "@protobase/schema": "0.19.2",
40
+ "@protobase/server": "0.19.2",
41
+ "@protobase/ui": "0.19.2",
42
42
  "@react-email/render": "^2.1.0",
43
43
  "@scalar/hono-api-reference": "^0.12.10",
44
44
  "@tailwindcss/vite": "^4.3.3",