nodality 1.0.161 → 1.0.163
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/bin/nodality.js +180 -0
- package/dist/bundle.umd.js +1 -1
- package/dist/designer.cjs.js +1 -1
- package/dist/designer.esm.js +1 -1
- package/dist/finalresult.esm.js +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/layout/animator.js +1 -1
- package/layout/audio.js +1 -1
- package/layout/audionew.js +1 -1
- package/layout/base-2.js +1 -1
- package/layout/base.js +1 -1
- package/layout/beta-desktop-bar.js +1 -1
- package/layout/beta-mobile-bar.js +1 -1
- package/layout/box.js +1 -1
- package/layout/button.js +1 -1
- package/layout/cards.js +1 -1
- package/layout/center.js +1 -1
- package/layout/checkbox.js +1 -1
- package/layout/circle.js +1 -1
- package/layout/clean-row.js +1 -1
- package/layout/code.js +1 -1
- package/layout/container.js +1 -1
- package/layout/custom.js +1 -1
- package/layout/div-image.js +1 -1
- package/layout/dropdown-2025.js +1 -1
- package/layout/dropdown.js +1 -1
- package/layout/empty-element.js +1 -1
- package/layout/external-stylesheet.js +1 -1
- package/layout/flex-card.js +1 -1
- package/layout/flex-grid.js +1 -1
- package/layout/flex-row.js +1 -1
- package/layout/footer.js +1 -1
- package/layout/form-components/custom.js +1 -1
- package/layout/form-components/data-list.js +1 -1
- package/layout/form-components/floating-input.js +1 -1
- package/layout/form-components/form-all.js +1 -1
- package/layout/form-components/form.js +1 -1
- package/layout/form-components/image-picker.js +1 -1
- package/layout/form-components/picker.js +1 -1
- package/layout/form-components/radio.js +1 -1
- package/layout/form-components/radiogroup.js +1 -1
- package/layout/form-components/range.js +1 -1
- package/layout/free.js +1 -1
- package/layout/grid-new.js +1 -1
- package/layout/grid-switcher.js +1 -1
- package/layout/grid.js +1 -1
- package/layout/group.js +1 -1
- package/layout/header.js +1 -1
- package/layout/horizontal-scroller.js +1 -1
- package/layout/image-old.js +1 -1
- package/layout/image.js +1 -1
- package/layout/index.js +1 -1
- package/layout/label.js +1 -1
- package/layout/link.js +1 -1
- package/layout/list-OLD.js +1 -1
- package/layout/list.js +1 -1
- package/layout/meta-adder.js +1 -1
- package/layout/modal-2025.js +1 -1
- package/layout/modernwrap.js +1 -1
- package/layout/multiswitcher.js +1 -1
- package/layout/multiswitcherBeta.js +1 -1
- package/layout/nav-bar.js +1 -1
- package/layout/nav-factor/custom-div.js +1 -1
- package/layout/navBar-OLD.js +1 -1
- package/layout/new-flat-adder.js +1 -1
- package/layout/new-nav-bar.js +1 -1
- package/layout/offset-container.js +1 -1
- package/layout/polygon.js +1 -1
- package/layout/prerender-site.js +1 -1
- package/layout/prerender.js +1 -1
- package/layout/progress.js +1 -1
- package/layout/row.js +1 -1
- package/layout/saved-new-nav-bar.js +1 -1
- package/layout/scroll-video.js +1 -1
- package/layout/side-bar.js +1 -1
- package/layout/side-nav-bar.js +1 -1
- package/layout/simple-bar.js +1 -1
- package/layout/slider-2025.js +1 -1
- package/layout/spacer.js +1 -1
- package/layout/stack.js +1 -1
- package/layout/styler.js +1 -1
- package/layout/svg.js +1 -1
- package/layout/switcher.js +1 -1
- package/layout/table.js +1 -1
- package/layout/text-field.js +1 -1
- package/layout/text.js +1 -1
- package/layout/ulist.js +1 -1
- package/layout/video.js +1 -1
- package/layout/without-new.js +1 -1
- package/layout/wrap.js +1 -1
- package/layout/zoom-card.js +1 -1
- package/lib/card-getter.js +1 -1
- package/lib/designer.js +10 -1
- package/lib/element-mapper.js +1 -1
- package/lib/keyframe-animation.js +1 -1
- package/lib/link-getter.js +1 -1
- package/lib/scroll-video.js +1 -1
- package/lib/stacker.js +1 -1
- package/lib/theme.js +1 -1
- package/lib/transform-anim.js +1 -1
- package/package.json +1 -1
package/bin/nodality.js
CHANGED
|
@@ -47,14 +47,88 @@ Prerender flags (all optional; fall through to nodality.config.json, then defaul
|
|
|
47
47
|
--tolerate-async Install uncaught/unhandledRejection handlers so a single page's
|
|
48
48
|
late throw (from a deferred animation/fetch timer) doesn't abort
|
|
49
49
|
the whole batch — useful for sites with span-animation entries.
|
|
50
|
+
--verbose Print every console.log() emitted by the library during render.
|
|
51
|
+
Default is quiet — only progress lines, page sizes, and the
|
|
52
|
+
final summary are shown. Use this when debugging.
|
|
50
53
|
|
|
51
54
|
Examples:
|
|
52
55
|
nodality prerender
|
|
53
56
|
nodality prerender --origin=https://example.com --tolerate-async
|
|
57
|
+
nodality prerender --verbose
|
|
54
58
|
`);
|
|
55
59
|
process.exit(1);
|
|
56
60
|
}
|
|
57
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Install a stdout filter that hides the library's internal debug
|
|
64
|
+
* chatter (OGA, MBO, BRIS, APPENDED-, 0P, TAGS SET, date stamps, raw
|
|
65
|
+
* object dumps, "Appending brand:" lines, etc.) during prerender.
|
|
66
|
+
* Progress banners from `prerenderSite` (page-name lines, `→ … KB`,
|
|
67
|
+
* `✅ Prerender done`) and our own `[nodality] …` banner pass through
|
|
68
|
+
* unmodified.
|
|
69
|
+
*
|
|
70
|
+
* Bypassed with --verbose (or NODALITY_VERBOSE=1) when you need the
|
|
71
|
+
* full chatter to debug a render that silently goes wrong.
|
|
72
|
+
*
|
|
73
|
+
* We hook process.stdout.write (not console.log) because the library
|
|
74
|
+
* has 100+ scattered console.log calls across 30 files, AND because
|
|
75
|
+
* jsdom's virtual console forwards differently than expected, AND
|
|
76
|
+
* because some output uses process.stdout.write directly. Filtering
|
|
77
|
+
* at the byte stream catches every path uniformly.
|
|
78
|
+
*/
|
|
79
|
+
function installLogFilter() {
|
|
80
|
+
const origWrite = process.stdout.write.bind(process.stdout);
|
|
81
|
+
|
|
82
|
+
// Strict whitelist: only lines matching one of these patterns
|
|
83
|
+
// survive. Everything else (dev markers, object dumps, stack traces
|
|
84
|
+
// from page scripts, HTML fragments leaking out of jsdom, media-
|
|
85
|
+
// query strings, date stamps, …) is dropped.
|
|
86
|
+
const ALLOW = [
|
|
87
|
+
/^\[nodality\]/, // our CLI banner
|
|
88
|
+
/^🌍/, // prerenderSite progress banner
|
|
89
|
+
/^✅/, /^❌/, /^⚠/, // status emojis
|
|
90
|
+
/^── /, // locale separators
|
|
91
|
+
/^ [a-z0-9\-]+\.html\s/, // page progress: " index.html ..."
|
|
92
|
+
/^→ /, // result lines
|
|
93
|
+
/^$/, // blank lines (preserve spacing)
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
function shouldDropLine(line) {
|
|
97
|
+
for (const rx of ALLOW) if (rx.test(line)) return false;
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Buffer partial lines so we can decide on line boundaries.
|
|
102
|
+
let buf = "";
|
|
103
|
+
|
|
104
|
+
process.stdout.write = function (chunk, encoding, cb) {
|
|
105
|
+
const s = typeof chunk === "string" ? chunk : chunk?.toString?.(encoding || "utf8") ?? "";
|
|
106
|
+
buf += s;
|
|
107
|
+
|
|
108
|
+
let out = "";
|
|
109
|
+
let nl;
|
|
110
|
+
while ((nl = buf.indexOf("\n")) !== -1) {
|
|
111
|
+
const line = buf.slice(0, nl);
|
|
112
|
+
buf = buf.slice(nl + 1);
|
|
113
|
+
if (!shouldDropLine(line)) out += line + "\n";
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// A trailing buffer with no newline is a progress write like
|
|
117
|
+
// ` index.html ` from prerender-site.js. Pass it
|
|
118
|
+
// through so the user sees progress before the line completes.
|
|
119
|
+
// We only do this when the buffered fragment passes the page-
|
|
120
|
+
// progress check; otherwise hold until newline.
|
|
121
|
+
if (buf && /^ [a-z0-9\-]+\.html\s/.test(buf)) {
|
|
122
|
+
out += buf;
|
|
123
|
+
buf = "";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (out) origWrite(out, encoding, cb);
|
|
127
|
+
else if (cb) cb();
|
|
128
|
+
return true;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
58
132
|
// ─── Flag parsing — minimal, no deps ────────────────────────────
|
|
59
133
|
|
|
60
134
|
function parseFlags(argv) {
|
|
@@ -81,6 +155,90 @@ function loadConfigFile(cwd) {
|
|
|
81
155
|
}
|
|
82
156
|
}
|
|
83
157
|
|
|
158
|
+
// ─── SSG bootstrap ──────────────────────────────────────────────
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* On first run, derive the upload/ structure from the project's root
|
|
162
|
+
* files so a freshly scaffolded project can prerender without manual
|
|
163
|
+
* setup. For each `src/<name>.js` we generate `upload/pages/<name>.js`
|
|
164
|
+
* (verbatim copy) and an `upload/<name>.html` whose importmap points
|
|
165
|
+
* at `./lib.bundle.js` and whose `<script src>` points at the page
|
|
166
|
+
* entry. The first src file (alphabetically) is also written as
|
|
167
|
+
* `upload/index.html` when no explicit index entry exists, so the
|
|
168
|
+
* dev server has a default landing page.
|
|
169
|
+
*
|
|
170
|
+
* If the user has already populated upload/ themselves, we touch
|
|
171
|
+
* nothing. Bootstrap only runs when upload/ is missing OR contains
|
|
172
|
+
* no .html files.
|
|
173
|
+
*/
|
|
174
|
+
function bootstrapUpload(cwd, uploadDir) {
|
|
175
|
+
const srcDir = path.join(cwd, "src");
|
|
176
|
+
if (!fs.existsSync(srcDir)) return false;
|
|
177
|
+
|
|
178
|
+
const srcFiles = fs.readdirSync(srcDir).filter((f) => f.endsWith(".js"));
|
|
179
|
+
if (srcFiles.length === 0) return false;
|
|
180
|
+
|
|
181
|
+
fs.mkdirSync(uploadDir, { recursive: true });
|
|
182
|
+
const pagesDir = path.join(uploadDir, "pages");
|
|
183
|
+
fs.mkdirSync(pagesDir, { recursive: true });
|
|
184
|
+
|
|
185
|
+
const projectName = path.basename(cwd);
|
|
186
|
+
let wrote = 0;
|
|
187
|
+
for (const srcFile of srcFiles) {
|
|
188
|
+
const base = path.basename(srcFile, ".js");
|
|
189
|
+
// Convention: src/app.js → upload/index.html + upload/pages/index.js.
|
|
190
|
+
// All others: src/<name>.js → upload/<name>.html + upload/pages/<name>.js.
|
|
191
|
+
const pageName = base === "app" ? "index" : base;
|
|
192
|
+
|
|
193
|
+
const entryPath = path.join(pagesDir, `${pageName}.js`);
|
|
194
|
+
if (!fs.existsSync(entryPath)) {
|
|
195
|
+
fs.copyFileSync(path.join(srcDir, srcFile), entryPath);
|
|
196
|
+
wrote++;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const htmlPath = path.join(uploadDir, `${pageName}.html`);
|
|
200
|
+
if (!fs.existsSync(htmlPath)) {
|
|
201
|
+
fs.writeFileSync(htmlPath, renderUploadHtml(projectName, pageName));
|
|
202
|
+
wrote++;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (wrote > 0) {
|
|
207
|
+
console.log(`[nodality] Bootstrapped upload/ from src/ (${wrote} file(s) written)`);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (!fs.existsSync(path.join(uploadDir, "lib.bundle.js"))) {
|
|
211
|
+
console.warn(
|
|
212
|
+
`[nodality] ⚠ upload/lib.bundle.js missing — run \`npm run build\` first ` +
|
|
213
|
+
`so the prerendered HTML can load the library bundle at runtime.`,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function renderUploadHtml(projectName, pageName) {
|
|
220
|
+
return `<!DOCTYPE html>
|
|
221
|
+
<html lang="en">
|
|
222
|
+
<head>
|
|
223
|
+
<meta charset="UTF-8">
|
|
224
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
225
|
+
<title>${projectName}</title>
|
|
226
|
+
<script type="importmap">
|
|
227
|
+
{
|
|
228
|
+
"imports": {
|
|
229
|
+
"nodality": "./lib.bundle.js"
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
</script>
|
|
233
|
+
</head>
|
|
234
|
+
<body>
|
|
235
|
+
<div id="mount"></div>
|
|
236
|
+
<script type="module" src="./pages/${pageName}.js"></script>
|
|
237
|
+
</body>
|
|
238
|
+
</html>
|
|
239
|
+
`;
|
|
240
|
+
}
|
|
241
|
+
|
|
84
242
|
// ─── Page auto-discovery ────────────────────────────────────────
|
|
85
243
|
|
|
86
244
|
/**
|
|
@@ -145,6 +303,18 @@ async function runPrerender(rawArgs) {
|
|
|
145
303
|
flags["tolerate-async"] === "true" ||
|
|
146
304
|
fileConfig.tolerateAsyncErrors === true;
|
|
147
305
|
|
|
306
|
+
// Quiet by default; --verbose or NODALITY_VERBOSE=1 turns the
|
|
307
|
+
// library's internal chatter back on. Only install the filter once
|
|
308
|
+
// (the multi-locale fanout re-enters this function in the parent
|
|
309
|
+
// process for the no-locales path, but on the child path
|
|
310
|
+
// NODALITY_SSG_LOCALE is set and we still want the filter on).
|
|
311
|
+
const verbose =
|
|
312
|
+
flags.verbose === true ||
|
|
313
|
+
flags.verbose === "true" ||
|
|
314
|
+
process.env.NODALITY_VERBOSE === "1" ||
|
|
315
|
+
fileConfig.verbose === true;
|
|
316
|
+
if (!verbose) installLogFilter();
|
|
317
|
+
|
|
148
318
|
if (!origin) {
|
|
149
319
|
console.error(`[nodality] --origin not given and no "origin" in nodality.config.json.`);
|
|
150
320
|
process.exit(1);
|
|
@@ -165,6 +335,16 @@ async function runPrerender(rawArgs) {
|
|
|
165
335
|
);
|
|
166
336
|
}
|
|
167
337
|
|
|
338
|
+
// First-run bootstrap: if upload/ is missing or has no HTML pages
|
|
339
|
+
// yet, derive it from the project's src/ + root index.html. This is
|
|
340
|
+
// what create-nodality projects rely on so the scaffolder doesn't
|
|
341
|
+
// have to ship duplicate copies of source files. No-op if upload/
|
|
342
|
+
// is already populated.
|
|
343
|
+
const needsBootstrap =
|
|
344
|
+
!fs.existsSync(uploadDir) ||
|
|
345
|
+
fs.readdirSync(uploadDir).filter((f) => f.endsWith(".html")).length === 0;
|
|
346
|
+
if (needsBootstrap) bootstrapUpload(cwd, uploadDir);
|
|
347
|
+
|
|
168
348
|
// Explicit `pages` from config wins over auto-discovery. The
|
|
169
349
|
// discovery rules (pages/<base>.js, <base>.js) can't infer
|
|
170
350
|
// irregular pairs like h7-nodality's `index.html → app.js`; for
|