@olenbetong/appframe-vite 6.15.0 → 6.16.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/lib/appEntry.d.ts +15 -0
- package/lib/appEntry.js +19 -0
- package/lib/appframeDataGlobal.js +2 -0
- package/lib/build.js +2 -9
- package/lib/cli-resources-migrate.js +4 -0
- package/lib/devServer.js +2 -10
- package/lib/index.js +14 -0
- package/lib/resourceGenerate.js +9 -2
- package/package.json +7 -7
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the app's entry module. Apps have no `index.html`: the dev server fetches the
|
|
3
|
+
* article's HTML from Synergi and injects a `<script type="module">` pointing at this file,
|
|
4
|
+
* and the production build uses it as the single rolldown input.
|
|
5
|
+
*
|
|
6
|
+
* `relative` is a POSIX path from the root, usable as a glob pattern (`optimizeDeps.entries`
|
|
7
|
+
* takes globs, and an absolute Windows path would be read as one with escapes in it).
|
|
8
|
+
* The last candidate is returned even when it does not exist, so a missing entry fails
|
|
9
|
+
* with a resolve error that names the file instead of a vaguer one later on.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getAppEntry(root?: string): {
|
|
12
|
+
absolute: string;
|
|
13
|
+
relative: string;
|
|
14
|
+
url: string;
|
|
15
|
+
};
|
package/lib/appEntry.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
/** The entry file candidates, in the order they are tried, relative to the app root. */
|
|
4
|
+
const ENTRY_CANDIDATES = ["src/index.tsx", "src/index.ts", "src/index.js"];
|
|
5
|
+
/**
|
|
6
|
+
* Resolves the app's entry module. Apps have no `index.html`: the dev server fetches the
|
|
7
|
+
* article's HTML from Synergi and injects a `<script type="module">` pointing at this file,
|
|
8
|
+
* and the production build uses it as the single rolldown input.
|
|
9
|
+
*
|
|
10
|
+
* `relative` is a POSIX path from the root, usable as a glob pattern (`optimizeDeps.entries`
|
|
11
|
+
* takes globs, and an absolute Windows path would be read as one with escapes in it).
|
|
12
|
+
* The last candidate is returned even when it does not exist, so a missing entry fails
|
|
13
|
+
* with a resolve error that names the file instead of a vaguer one later on.
|
|
14
|
+
*/
|
|
15
|
+
export function getAppEntry(root = process.cwd()) {
|
|
16
|
+
let found = ENTRY_CANDIDATES.find((candidate) => existsSync(resolve(root, candidate)));
|
|
17
|
+
let relative = found ?? ENTRY_CANDIDATES[ENTRY_CANDIDATES.length - 1];
|
|
18
|
+
return { absolute: resolve(root, relative), relative, url: `/${relative}` };
|
|
19
|
+
}
|
package/lib/build.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
1
|
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
3
2
|
import { dirname, resolve } from "node:path";
|
|
4
3
|
import { visualizer } from "rollup-plugin-visualizer";
|
|
5
4
|
import { esmExternalRequirePlugin } from "vite";
|
|
5
|
+
import { getAppEntry } from "./appEntry.js";
|
|
6
6
|
import { importJson } from "./importJson.js";
|
|
7
7
|
/**
|
|
8
8
|
* The bare specifiers the 2026 site templates resolve through their import map to the
|
|
@@ -202,16 +202,9 @@ export async function addAppframeBuildConfig(config) {
|
|
|
202
202
|
sourcemap: true,
|
|
203
203
|
};
|
|
204
204
|
config.plugins = config.plugins ?? [];
|
|
205
|
-
let entry = resolve(process.cwd(), "./src/index.tsx");
|
|
206
|
-
if (!existsSync(resolve(entry))) {
|
|
207
|
-
entry = resolve(process.cwd(), "./src/index.ts");
|
|
208
|
-
}
|
|
209
|
-
if (!existsSync(resolve(entry))) {
|
|
210
|
-
entry = resolve(process.cwd(), "./src/index.js");
|
|
211
|
-
}
|
|
212
205
|
config.appType = "custom";
|
|
213
206
|
config.build.rolldownOptions = {
|
|
214
|
-
input: { main:
|
|
207
|
+
input: { main: getAppEntry().absolute },
|
|
215
208
|
plugins: [
|
|
216
209
|
// Cast visualizer plugin to any to avoid Rollup type version clashes
|
|
217
210
|
visualizer({ filename: "./dist/stats.html", gzipSize: true }),
|
|
@@ -182,6 +182,10 @@ function dataObjectToEntry(datasource, fields, outputDir, warnings) {
|
|
|
182
182
|
if (sortFields.length > 0) {
|
|
183
183
|
entry.sortOrder = sortFields.map((f) => {
|
|
184
184
|
let direction = (f.AscDesc ?? "asc").toLowerCase();
|
|
185
|
+
// Keep the null placement of AscNullsLast / DescNullsFirst
|
|
186
|
+
if (direction === "ascnullslast" || direction === "descnullsfirst") {
|
|
187
|
+
return { field: f.FieldName, direction };
|
|
188
|
+
}
|
|
185
189
|
return direction.startsWith("desc") ? { field: f.FieldName, direction: "desc" } : { field: f.FieldName };
|
|
186
190
|
});
|
|
187
191
|
}
|
package/lib/devServer.js
CHANGED
|
@@ -5,6 +5,7 @@ import { AuthenticationError, authenticate, loginHint, resolveCredentials } from
|
|
|
5
5
|
import { Client } from "@olenbetong/appframe-data";
|
|
6
6
|
import dotenv from "dotenv";
|
|
7
7
|
import { JSDOM } from "jsdom";
|
|
8
|
+
import { getAppEntry } from "./appEntry.js";
|
|
8
9
|
import { importJson } from "./importJson.js";
|
|
9
10
|
import { getStringCache } from "./localization.js";
|
|
10
11
|
import { diagnoseServerResponse } from "./utils.js";
|
|
@@ -68,16 +69,7 @@ export function getProxyRoutes() {
|
|
|
68
69
|
* @returns
|
|
69
70
|
*/
|
|
70
71
|
async function transformArticleHtml(html) {
|
|
71
|
-
let entry;
|
|
72
|
-
if (existsSync(resolve(process.cwd(), "./src/index.tsx"))) {
|
|
73
|
-
entry = "/src/index.tsx";
|
|
74
|
-
}
|
|
75
|
-
else if (existsSync(resolve(process.cwd(), "./src/index.ts"))) {
|
|
76
|
-
entry = "/src/index.ts";
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
entry = "/src/index.js";
|
|
80
|
-
}
|
|
72
|
+
let entry = getAppEntry().url;
|
|
81
73
|
let article = appframe.article?.id;
|
|
82
74
|
let { hostname } = await getAppHostname();
|
|
83
75
|
let dom = new JSDOM(html);
|
package/lib/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import bodyParser from "body-parser";
|
|
4
4
|
import { watch } from "chokidar";
|
|
5
|
+
import { getAppEntry } from "./appEntry.js";
|
|
5
6
|
import { appframeDataGlobal } from "./appframeDataGlobal.js";
|
|
6
7
|
import { addAppframeBuildConfig, PLATFORM_EXTERNALS, PLATFORM_GLOBALS, PLATFORM_UPSTREAM, platformManifest, usesPlatform, } from "./build.js";
|
|
7
8
|
import { generateFromConfig } from "./cli-resources-generate.js";
|
|
@@ -184,6 +185,19 @@ export default function appframe(options = {}) {
|
|
|
184
185
|
...config.server,
|
|
185
186
|
proxy,
|
|
186
187
|
};
|
|
188
|
+
// Apps have no index.html, so the dependency scanner Vite runs at startup has
|
|
189
|
+
// nothing to crawl (it globs "**/*.html") and skips pre-bundling altogether. Every
|
|
190
|
+
// dependency is then discovered when a module first imports it: the ones behind
|
|
191
|
+
// the initial page load are batched, but a lazy route that pulls in a new one
|
|
192
|
+
// re-runs the optimizer and forces a full reload, which lands back on the page
|
|
193
|
+
// you navigated from. Crawling from the entry module finds the lazy imports up
|
|
194
|
+
// front, so the deps are ready before the browser asks for them.
|
|
195
|
+
if (!config.optimizeDeps?.entries) {
|
|
196
|
+
config.optimizeDeps = {
|
|
197
|
+
...config.optimizeDeps,
|
|
198
|
+
entries: [getAppEntry().relative],
|
|
199
|
+
};
|
|
200
|
+
}
|
|
187
201
|
}
|
|
188
202
|
return config;
|
|
189
203
|
},
|
package/lib/resourceGenerate.js
CHANGED
|
@@ -169,6 +169,13 @@ export function parseYamlConfig(fileContent) {
|
|
|
169
169
|
// ---------------------------------------------------------------------------
|
|
170
170
|
// Code generation helpers
|
|
171
171
|
// ---------------------------------------------------------------------------
|
|
172
|
+
/**
|
|
173
|
+
* A field name as an object key in generated code, quoted when it is not a valid identifier,
|
|
174
|
+
* such as a view column named `EU-Neste`.
|
|
175
|
+
*/
|
|
176
|
+
function propertyKey(name) {
|
|
177
|
+
return /^[A-Za-z_$][\w$]*$/.test(name) ? name : JSON.stringify(name);
|
|
178
|
+
}
|
|
172
179
|
/**
|
|
173
180
|
* Convert Appframe (SQL) data types to typescript/field definition types
|
|
174
181
|
*/
|
|
@@ -394,7 +401,7 @@ export function getDataObjectDefinition(name, viewDefinition, options) {
|
|
|
394
401
|
type += " | null";
|
|
395
402
|
}
|
|
396
403
|
}
|
|
397
|
-
fieldTypes += ` ${field.name}: ${type};\n`;
|
|
404
|
+
fieldTypes += ` ${propertyKey(field.name)}: ${type};\n`;
|
|
398
405
|
}
|
|
399
406
|
types = `export type ${typeName} = {
|
|
400
407
|
${fieldTypes}}`;
|
|
@@ -465,7 +472,7 @@ ${fieldTypes}}`;
|
|
|
465
472
|
order = "DescNullsFirst";
|
|
466
473
|
break;
|
|
467
474
|
}
|
|
468
|
-
return `{ ${field}: ${sortPrefix}${order} }`;
|
|
475
|
+
return `{ ${propertyKey(field)}: ${sortPrefix}${order} }`;
|
|
469
476
|
})
|
|
470
477
|
.join(", ");
|
|
471
478
|
parametersOption.push(`sortOrder: [${sortOrder}]`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olenbetong/appframe-vite",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.16.0",
|
|
4
4
|
"description": "Tools to use and deploy Vite applications to Appframe",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -30,24 +30,24 @@
|
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@olenbetong/appframe-auth": "^0.1.0",
|
|
33
|
-
"@olenbetong/appframe-data": "^1.8.
|
|
33
|
+
"@olenbetong/appframe-data": "^1.8.3",
|
|
34
34
|
"body-parser": "^2.3.0",
|
|
35
35
|
"chalk": "6.0.1",
|
|
36
36
|
"chokidar": "^5.0.0",
|
|
37
37
|
"commander": "15.0.0",
|
|
38
|
-
"dotenv": "^18.0.
|
|
38
|
+
"dotenv": "^18.0.8",
|
|
39
39
|
"fuzzy": "^0.1.3",
|
|
40
|
-
"inquirer": "^14.2.
|
|
40
|
+
"inquirer": "^14.2.4",
|
|
41
41
|
"inquirer-autocomplete-standalone": "^0.8.1",
|
|
42
|
-
"jsdom": "30.1.
|
|
42
|
+
"jsdom": "30.1.3",
|
|
43
43
|
"rollup-plugin-visualizer": "^7.1.1",
|
|
44
44
|
"yaml": "^2.9.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/jsdom": "^30.0.0",
|
|
48
|
-
"@types/node": "26.6.
|
|
48
|
+
"@types/node": "26.6.5",
|
|
49
49
|
"typescript": "7.0.2",
|
|
50
|
-
"vite": "8.3.
|
|
50
|
+
"vite": "8.3.5"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"vite": ">=8.1.5"
|