@canopy-iiif/app 0.12.6 → 0.12.7

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/lib/AGENTS.md CHANGED
@@ -65,6 +65,7 @@ Logbook
65
65
  - 2025-09-27 / chatgpt: Documented Tailwind token flow in `app/styles/tailwind.config.mts`, compiled UI Sass variables during config load, and exposed `stylesheetHref`/`Stylesheet` helpers via `@canopy-iiif/app/head` so `_app.mdx` can reference the generated CSS directly.
66
66
  - 2025-09-27 / chatgpt: Expanded search indexing to harvest MDX pages (respecting frontmatter/layout types), injected BASE_PATH hydration data into search.html, and reworked `mdx.extractTitle()` so generated records surface real headings instead of `Untitled`.
67
67
  - 2025-10-19 / chatgpt: Embedded the Tailwind preset/plugin in a packaged config so dev/build fall back automatically; removed `app/styles/tailwind.config.*` from the default app and switched the public stylesheet to Tailwind’s CSS-first (`@import 'tailwindcss'; @theme { ... }`) workflow.
68
+ - 2025-10-20 / chatgpt: Added `lib/config-path.js` to resolve `canopy.yml` from the workspace root (preferring `options.cwd`, then npm `INIT_CWD`, then `process.cwd()`) and updated all loaders (theme, common base URL, search metadata, IIIF builder, featured manifests) to use it so hosted builds and Tailwind runs inside `node_modules/@canopy-iiif/app/ui` pick up user theme settings.
68
69
 
69
70
  Verification Commands
70
71
  ---------------------
package/lib/build/iiif.js CHANGED
@@ -14,6 +14,7 @@ const {
14
14
  rootRelativeHref,
15
15
  canopyBodyClassForType,
16
16
  } = require("../common");
17
+ const {resolveCanopyConfigPath} = require("../config-path");
17
18
  const mdx = require("./mdx");
18
19
  const {log, logLine, logResponse} = require("./log");
19
20
  const { getPageContext } = require("../page-context");
@@ -1109,7 +1110,7 @@ async function rebuildManifestIndexFromCache() {
1109
1110
  }
1110
1111
 
1111
1112
  async function loadConfig() {
1112
- const cfgPath = path.resolve("canopy.yml");
1113
+ const cfgPath = resolveCanopyConfigPath();
1113
1114
  if (!fs.existsSync(cfgPath)) return {};
1114
1115
  const raw = await fsp.readFile(cfgPath, "utf8");
1115
1116
  let cfg = {};
package/lib/common.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const fsp = fs.promises;
3
3
  const path = require('path');
4
+ const { resolveCanopyConfigPath } = require('./config-path');
4
5
 
5
6
  const CONTENT_DIR = path.resolve('content');
6
7
  const OUT_DIR = path.resolve('site');
@@ -29,7 +30,7 @@ function resolveThemeAppearance() {
29
30
  function readYamlConfigBaseUrl() {
30
31
  try {
31
32
  const y = require('js-yaml');
32
- const p = path.resolve(process.env.CANOPY_CONFIG || 'canopy.yml');
33
+ const p = resolveCanopyConfigPath();
33
34
  if (!fs.existsSync(p)) return '';
34
35
  const raw = fs.readFileSync(p, 'utf8');
35
36
  const data = y.load(raw) || {};
@@ -2,6 +2,7 @@ const fs = require('fs');
2
2
  const path = require('path');
3
3
  const yaml = require('js-yaml');
4
4
  const { rootRelativeHref } = require('../common');
5
+ const { resolveCanopyConfigPath } = require('../config-path');
5
6
 
6
7
  function firstLabelString(label) {
7
8
  if (!label) return 'Untitled';
@@ -85,7 +86,7 @@ function findSlugByIdFromDiskSync(nid) {
85
86
  function readFeaturedFromCacheSync() {
86
87
  try {
87
88
  const debug = !!process.env.CANOPY_DEBUG_FEATURED;
88
- const cfg = readYaml(path.resolve('canopy.yml')) || {};
89
+ const cfg = readYaml(resolveCanopyConfigPath()) || {};
89
90
  const featured = Array.isArray(cfg && cfg.featured) ? cfg.featured : [];
90
91
  if (!featured.length) return [];
91
92
  const idx = readJson(path.resolve('.cache/iiif/index.json')) || {};
@@ -0,0 +1,28 @@
1
+ const path = require('path');
2
+
3
+ const DEFAULT_CONFIG_NAME = 'canopy.yml';
4
+
5
+ function resolveWorkspaceRoot(options = {}) {
6
+ const rawCwd = options && options.cwd ? String(options.cwd).trim() : '';
7
+ if (rawCwd) return path.resolve(rawCwd);
8
+ const initCwd = String(process.env.INIT_CWD || '').trim();
9
+ if (initCwd) return path.resolve(initCwd);
10
+ return process.cwd();
11
+ }
12
+
13
+ function resolveCanopyConfigPath(options = {}) {
14
+ const root = resolveWorkspaceRoot(options);
15
+ const explicit = options && options.configPath ? String(options.configPath).trim() : '';
16
+ if (explicit) {
17
+ return path.isAbsolute(explicit) ? explicit : path.resolve(root, explicit);
18
+ }
19
+ const override = options && options.configFile ? String(options.configFile).trim() : '';
20
+ const envOverride = String(process.env.CANOPY_CONFIG || '').trim();
21
+ const fileName = override || envOverride || DEFAULT_CONFIG_NAME;
22
+ return path.resolve(root, fileName);
23
+ }
24
+
25
+ module.exports = {
26
+ resolveWorkspaceRoot,
27
+ resolveCanopyConfigPath,
28
+ };
@@ -12,6 +12,7 @@ const {
12
12
  htmlShell,
13
13
  canopyBodyClassForType,
14
14
  } = require('../common');
15
+ const { resolveCanopyConfigPath } = require('../config-path');
15
16
 
16
17
  const SEARCH_TEMPLATES_ALIAS = '__CANOPY_SEARCH_RESULT_TEMPLATES__';
17
18
  const SEARCH_TEMPLATES_CACHE_DIR = path.resolve('.cache/search');
@@ -444,10 +445,9 @@ async function writeSearchIndex(records) {
444
445
  let resultsConfigEntries = [];
445
446
  try {
446
447
  const yaml = require('js-yaml');
447
- const common = require('../common');
448
- const cfgPath = common.path.resolve(process.env.CANOPY_CONFIG || 'canopy.yml');
449
- if (common.fs.existsSync(cfgPath)) {
450
- const raw = common.fs.readFileSync(cfgPath, 'utf8');
448
+ const cfgPath = resolveCanopyConfigPath();
449
+ if (fs.existsSync(cfgPath)) {
450
+ const raw = fs.readFileSync(cfgPath, 'utf8');
451
451
  const data = yaml.load(raw) || {};
452
452
  const searchCfg = data && data.search ? data.search : {};
453
453
  const tabs = searchCfg && searchCfg.tabs ? searchCfg.tabs : {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canopy-iiif/app",
3
- "version": "0.12.6",
3
+ "version": "0.12.7",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "author": "Mat Jordan <mat@northwestern.edu>",
package/ui/theme.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const fs = require("fs");
2
- const path = require("path");
3
2
  const yaml = require("js-yaml");
4
3
  const radixColors = require("@radix-ui/colors");
4
+ const {resolveCanopyConfigPath} = require("../lib/config-path");
5
5
 
6
6
  const DEFAULT_ACCENT = "indigo";
7
7
  const DEFAULT_GRAY = "slate";
@@ -205,10 +205,7 @@ function buildSassConfig(brandScale, grayScale) {
205
205
  }
206
206
 
207
207
  function loadCanopyTheme(options = {}) {
208
- const cwd = options.cwd || process.cwd();
209
- const cfgPath =
210
- options.configPath ||
211
- path.resolve(cwd, process.env.CANOPY_CONFIG || "canopy.yml");
208
+ const cfgPath = resolveCanopyConfigPath(options);
212
209
  const cfg = readYamlConfig(cfgPath);
213
210
  const theme = (cfg && cfg.theme) || {};
214
211
  const accentRequested = theme && theme.accentColor;