@aippy/vite-plugins 0.4.0-dev.2 → 0.4.0-dev.3
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/README.md +3 -5
- package/dist/aippy-preload/html-utils.d.ts +0 -5
- package/dist/aippy-preload/index.js +1 -1
- package/dist/aippy-preload-DtngFmJ5.js +186 -0
- package/dist/asset-constants/generator-utils.d.ts +5 -6
- package/dist/asset-constants/index.js +325 -2
- package/dist/{manifest-DQGCd9CQ.js → generator-utils-CFYv7n_h.js} +41 -5
- package/dist/index/index.js +2 -2
- package/package.json +1 -1
- package/src/asset-constants/assets.schema.json +1 -0
- package/dist/aippy-preload-Dhhw3O6d.js +0 -170
- package/dist/asset-constants-BUK7zWRd.js +0 -360
package/README.md
CHANGED
|
@@ -102,10 +102,8 @@ const projectRoot = findProjectRoot(); // '/path/to/project'
|
|
|
102
102
|
|
|
103
103
|
UNLICENSED - Aippy Team
|
|
104
104
|
|
|
105
|
-
## Asset
|
|
105
|
+
## Asset files
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
`src/config/assets.json` is a flat URL dictionary. The plugin writes only that file. The project-root `assets-plan.json` is read-only input for reserved names and `implementation.path` exclusions; a missing or unreadable plan does not stop the build. Invalid dictionary JSON, or a single-file v1 plan stored in the dictionary, stops the build without overwriting the file.
|
|
108
108
|
|
|
109
|
-
Import the generated
|
|
110
|
-
|
|
111
|
-
Pending the next dev release, wrappers retain only historical flat placeholder keys listed in `legacyPlaceholderKeys` as empty strings; other unavailable media remain absent. Concrete code assets continue to use their source references. These changes are not included in the published 0.4.0-dev.1 package.
|
|
109
|
+
Import the generated map from `@/config/assets`. It exports the dictionary's string values. `window.getReplacedAssets` still mutates that object in place. Preload reads those string values and URLs in other source files, not prompts inside the plan. The JSON schema remains `@aippy/vite-plugins/assets.schema.json`. Version 0.4.0-dev.3 is prepared locally and is not published yet.
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HTML processing utilities for aippy preload plugin
|
|
3
3
|
*/
|
|
4
|
-
/**
|
|
5
|
-
* Generate meta tags for asset preloading
|
|
6
|
-
* @param assets - Array of asset URLs
|
|
7
|
-
* @returns HTML meta tags string
|
|
8
|
-
*/
|
|
9
4
|
export declare function generateMetaTags(assets: string[]): string;
|
|
10
5
|
/**
|
|
11
6
|
* Inject meta tags into HTML content
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "../aippy-preload-
|
|
1
|
+
import { t as e } from "../aippy-preload-DtngFmJ5.js";
|
|
2
2
|
export { e as aippyPreloadPlugin, e as default };
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { extractAssetsFromContent as e, isValidAsset as t } from "./utils/index.js";
|
|
2
|
+
import { a as n, l as r, m as i, n as a, o, s } from "./generator-utils-CFYv7n_h.js";
|
|
3
|
+
import { promises as c } from "fs";
|
|
4
|
+
import l from "path";
|
|
5
|
+
//#region src/aippy-preload/scanner-utils.ts
|
|
6
|
+
async function u(t) {
|
|
7
|
+
let n = [], r = [l.join(process.cwd(), "index.html")];
|
|
8
|
+
for (let i of r) try {
|
|
9
|
+
let r = await c.readFile(i, "utf-8"), a = e(r, "html", t);
|
|
10
|
+
n.push(...a);
|
|
11
|
+
} catch {
|
|
12
|
+
console.warn("⚠️ No index.html found in project root");
|
|
13
|
+
}
|
|
14
|
+
return n;
|
|
15
|
+
}
|
|
16
|
+
async function d(t, n) {
|
|
17
|
+
let u = [], d = l.resolve(t, "config/assets.json"), f, p = /* @__PURE__ */ new Set();
|
|
18
|
+
try {
|
|
19
|
+
let e = JSON.parse(await c.readFile(d, "utf8"));
|
|
20
|
+
if (a(e)) {
|
|
21
|
+
let t = s(JSON.stringify(e));
|
|
22
|
+
o(t) && (f = t);
|
|
23
|
+
} else e && typeof e == "object" && !Array.isArray(e) && (p = new Set(Object.keys(e)));
|
|
24
|
+
} catch {}
|
|
25
|
+
let m = await i(t, [
|
|
26
|
+
".ts",
|
|
27
|
+
".tsx",
|
|
28
|
+
".js",
|
|
29
|
+
".jsx"
|
|
30
|
+
]);
|
|
31
|
+
for (let i of m) try {
|
|
32
|
+
if (f && l.resolve(i) === d.replace(/\.json$/, ".ts")) continue;
|
|
33
|
+
let a = await c.readFile(i, "utf-8"), o = e(a, "js", n), s = /* @__PURE__ */ new Set([...p, ...f ? Object.keys(f.assets) : []]);
|
|
34
|
+
o.some((e) => s.has(e)) && (o = e(r(a, i, t, d), "js", n)), u.push(...o);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.warn(`⚠️ Failed to read JS file: ${i}`, e);
|
|
37
|
+
}
|
|
38
|
+
return u;
|
|
39
|
+
}
|
|
40
|
+
async function f(t, n) {
|
|
41
|
+
let r = [], a = await i(t, [
|
|
42
|
+
".css",
|
|
43
|
+
".scss",
|
|
44
|
+
".sass",
|
|
45
|
+
".less"
|
|
46
|
+
]);
|
|
47
|
+
for (let t of a) try {
|
|
48
|
+
let i = await c.readFile(t, "utf-8"), a = e(i, "css", n);
|
|
49
|
+
r.push(...a);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
console.warn(`⚠️ Failed to read CSS file: ${t}`, e);
|
|
52
|
+
}
|
|
53
|
+
return r;
|
|
54
|
+
}
|
|
55
|
+
function p(e, n) {
|
|
56
|
+
if (!t(e) || /["'<>\s`]/.test(e)) return !1;
|
|
57
|
+
let r = e.split(/[?#]/, 1)[0].toLowerCase();
|
|
58
|
+
return n.some((e) => r.endsWith(e.toLowerCase()));
|
|
59
|
+
}
|
|
60
|
+
async function m(t, r) {
|
|
61
|
+
let u = [], d = await i(t, [".json"]);
|
|
62
|
+
for (let i of d) try {
|
|
63
|
+
let d = await c.readFile(i, "utf-8");
|
|
64
|
+
if (l.basename(i) === "assets-plan.json") continue;
|
|
65
|
+
if (l.resolve(i) === l.resolve(t, "config/assets.json")) {
|
|
66
|
+
let e = JSON.parse(d);
|
|
67
|
+
if (a(e)) {
|
|
68
|
+
let e = s(d);
|
|
69
|
+
if (o(e)) {
|
|
70
|
+
u.push(...Object.values(n(e)));
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (e && typeof e == "object" && !Array.isArray(e)) {
|
|
75
|
+
for (let t of Object.values(e)) typeof t == "string" && p(t, r) && u.push(t);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
let f = e(d, "js", r);
|
|
80
|
+
u.push(...f);
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.warn(`⚠️ Failed to read JSON file: ${i}`, e);
|
|
83
|
+
}
|
|
84
|
+
return u;
|
|
85
|
+
}
|
|
86
|
+
async function h(e, t, n) {
|
|
87
|
+
console.log("🔍 Scanning source files for static assets...");
|
|
88
|
+
let r = [];
|
|
89
|
+
if (n) {
|
|
90
|
+
console.log("🔍 Deep scanning source file contents...");
|
|
91
|
+
let [n, i, a, o] = await Promise.all([
|
|
92
|
+
u(t),
|
|
93
|
+
d(e, t),
|
|
94
|
+
f(e, t),
|
|
95
|
+
m(e, t)
|
|
96
|
+
]);
|
|
97
|
+
r.push(...n, ...i, ...a, ...o);
|
|
98
|
+
}
|
|
99
|
+
return [...new Set(r)];
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/aippy-preload/html-utils.ts
|
|
103
|
+
var g = "<head>", _ = 6;
|
|
104
|
+
function v(e) {
|
|
105
|
+
return e.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
106
|
+
}
|
|
107
|
+
function y(e) {
|
|
108
|
+
return e.map((e) => ` <meta content="${v(e)}" name="aippy:preload">`).join("\n");
|
|
109
|
+
}
|
|
110
|
+
function b(e, t) {
|
|
111
|
+
let n = e.indexOf(g);
|
|
112
|
+
if (n === -1) throw Error("Could not find <head> tag in HTML");
|
|
113
|
+
let r = n + _;
|
|
114
|
+
return e.slice(0, r) + "\n" + t + "\n" + e.slice(r);
|
|
115
|
+
}
|
|
116
|
+
function x(e) {
|
|
117
|
+
let t = e.length;
|
|
118
|
+
if (console.log(`📁 Found ${t} static ${t === 1 ? "asset" : "assets"} in source files`), t === 0) {
|
|
119
|
+
console.log("⚠️ No static assets found in source files.");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
console.log(`📋 ${t === 1 ? "Asset" : "Assets"} found:`), e.forEach((e) => console.log(` - ${e}`));
|
|
123
|
+
}
|
|
124
|
+
function S(e) {
|
|
125
|
+
console.log(`✅ Injected ${e} preload meta ${e === 1 ? "tag" : "tags"} into index.html`);
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/aippy-preload/index.ts
|
|
129
|
+
var C = 3, w = 1e3;
|
|
130
|
+
function T(e) {
|
|
131
|
+
return new Promise((t) => setTimeout(t, e));
|
|
132
|
+
}
|
|
133
|
+
async function E(e, t = C, n = w) {
|
|
134
|
+
for (let r = 1; r <= t; r++) try {
|
|
135
|
+
return await c.readFile(e, "utf-8");
|
|
136
|
+
} catch (e) {
|
|
137
|
+
if (e.code === "ENOENT") {
|
|
138
|
+
if (r < t) {
|
|
139
|
+
console.log(`⏳ index.html not found, waiting ${n}ms before retry (attempt ${r}/${t})...`), await T(n);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
return console.log(`⚠️ index.html not found after ${t} attempts, skipping preload injection.`), null;
|
|
143
|
+
}
|
|
144
|
+
return console.error("❌ Error reading index.html:", e), null;
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
function D(e = {}) {
|
|
149
|
+
let t = {
|
|
150
|
+
extensions: [
|
|
151
|
+
".png",
|
|
152
|
+
".jpg",
|
|
153
|
+
".jpeg",
|
|
154
|
+
".gif",
|
|
155
|
+
".svg",
|
|
156
|
+
".mp4",
|
|
157
|
+
".mp3",
|
|
158
|
+
".wav",
|
|
159
|
+
".ogg",
|
|
160
|
+
".webm"
|
|
161
|
+
],
|
|
162
|
+
srcDir: "src",
|
|
163
|
+
outDir: "dist",
|
|
164
|
+
deepScan: !0,
|
|
165
|
+
...e
|
|
166
|
+
};
|
|
167
|
+
return {
|
|
168
|
+
name: "vite-plugin-aippy-preload",
|
|
169
|
+
apply: "build",
|
|
170
|
+
enforce: "post",
|
|
171
|
+
async writeBundle() {
|
|
172
|
+
try {
|
|
173
|
+
let e = await h(t.srcDir, t.extensions, t.deepScan);
|
|
174
|
+
if (x(e), e.length === 0) return;
|
|
175
|
+
let n = l.join(t.outDir, "index.html"), r = await E(n);
|
|
176
|
+
if (r === null) return;
|
|
177
|
+
let i = b(r, y(e));
|
|
178
|
+
await c.writeFile(n, i, "utf-8"), S(e.length);
|
|
179
|
+
} catch (e) {
|
|
180
|
+
console.error("❌ Error in aippy preload plugin:", e);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
//#endregion
|
|
186
|
+
export { D as t };
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { AssetInfo } from './types';
|
|
2
|
-
|
|
2
|
+
/** A flat dictionary is a v1 plan only when schemaVersion is a number and assets is an object. */
|
|
3
|
+
export declare function isSingleFilePlan(value: unknown): boolean;
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* @param existingAssets - Map of existing assets from previous runs
|
|
7
|
-
* @returns JSON string
|
|
5
|
+
* Write the flat dictionary. Existing keys and non-string values stay; scanned
|
|
6
|
+
* resources only add a key when that URL is not already present.
|
|
8
7
|
*/
|
|
9
|
-
export declare function generateAssetsFileContent(assets: Map<string, AssetInfo>, existingAssets: Map<string, string>,
|
|
8
|
+
export declare function generateAssetsFileContent(assets: Map<string, AssetInfo>, existingAssets: Map<string, string>, flat?: Record<string, unknown>): string;
|
|
10
9
|
/**
|
|
11
10
|
* Parse existing assets.json file
|
|
12
11
|
* @param content - File content
|
|
@@ -1,2 +1,325 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { extractAssetsFromContent as e, generateConstantName as t, processAssetURL as n } from "../utils/index.js";
|
|
2
|
+
import { c as r, d as i, f as a, g as o, h as s, i as c, l, m as u, n as d, o as f, p, r as m, s as h, t as g, u as _ } from "../generator-utils-CFYv7n_h.js";
|
|
3
|
+
import { promises as v } from "fs";
|
|
4
|
+
import y from "path";
|
|
5
|
+
import { parse as b } from "@babel/parser";
|
|
6
|
+
import x from "@babel/traverse";
|
|
7
|
+
import * as S from "@babel/types";
|
|
8
|
+
import C from "@babel/generator";
|
|
9
|
+
//#region src/asset-constants/index.ts
|
|
10
|
+
var w = typeof x == "function" ? x : x.default, T = typeof C == "function" ? C : C.default, E = class extends Error {}, D = class {
|
|
11
|
+
isStructuredInventory() {
|
|
12
|
+
return this.document !== void 0 && f(this.document);
|
|
13
|
+
}
|
|
14
|
+
constructor(e = {}) {
|
|
15
|
+
o(this, "options", void 0), o(this, "assets", /* @__PURE__ */ new Map()), o(this, "existingAssets", /* @__PURE__ */ new Map()), o(this, "flat", {}), o(this, "fileCache", new a()), o(this, "document", void 0), o(this, "implementationPaths", /* @__PURE__ */ new Set()), this.options = {
|
|
16
|
+
extensions: [
|
|
17
|
+
".png",
|
|
18
|
+
".jpg",
|
|
19
|
+
".jpeg",
|
|
20
|
+
".gif",
|
|
21
|
+
".svg",
|
|
22
|
+
".mp4",
|
|
23
|
+
".mp3",
|
|
24
|
+
".wav",
|
|
25
|
+
".ogg",
|
|
26
|
+
".webm"
|
|
27
|
+
],
|
|
28
|
+
srcDir: "src",
|
|
29
|
+
outputFile: "src/config/assets.json",
|
|
30
|
+
devMode: !1,
|
|
31
|
+
...e
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
clearCache() {
|
|
35
|
+
this.fileCache.clear();
|
|
36
|
+
}
|
|
37
|
+
generateConstantName(e) {
|
|
38
|
+
let n = /* @__PURE__ */ new Set([
|
|
39
|
+
...Array.from(this.assets.values()).map((e) => e.constantName),
|
|
40
|
+
...Array.from(this.existingAssets.values()),
|
|
41
|
+
...this.document && f(this.document) ? Object.keys(this.document.assets) : []
|
|
42
|
+
]);
|
|
43
|
+
return t(e, n);
|
|
44
|
+
}
|
|
45
|
+
async scanTsFile(t) {
|
|
46
|
+
try {
|
|
47
|
+
let n = await this.fileCache.read(t), r = [], i = e(n, "js", this.options.extensions), a = /* @__PURE__ */ new Set([...Object.keys(this.flat), ...this.document && f(this.document) ? Object.keys(this.document.assets) : []]);
|
|
48
|
+
if (i.some((e) => a.has(e))) {
|
|
49
|
+
let r = l(n, t, this.options.srcDir, this.options.outputFile);
|
|
50
|
+
i = e(r, "js", this.options.extensions);
|
|
51
|
+
}
|
|
52
|
+
let o = n.split("\n");
|
|
53
|
+
return i.forEach((e) => {
|
|
54
|
+
if (this.isImplementationReference(t, e)) return;
|
|
55
|
+
let n = this.generateConstantName(e), i = o.findIndex((t) => t.includes(e)) + 1;
|
|
56
|
+
r.push({
|
|
57
|
+
originalUri: e,
|
|
58
|
+
constantName: n,
|
|
59
|
+
filePath: t,
|
|
60
|
+
line: i,
|
|
61
|
+
column: 1
|
|
62
|
+
});
|
|
63
|
+
}), r;
|
|
64
|
+
} catch (e) {
|
|
65
|
+
return console.warn(`Warning: Failed to scan ${t}:`, e), [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async scanAllTsFiles() {
|
|
69
|
+
let e = this.options.srcDir;
|
|
70
|
+
try {
|
|
71
|
+
let t = await u(e, [".ts", ".tsx"]);
|
|
72
|
+
for (let e of t) e.endsWith("assets.json") || e.endsWith("assets.ts") || (await this.scanTsFile(e)).forEach((e) => {
|
|
73
|
+
this.existingAssets.has(e.originalUri) && (e.constantName = this.existingAssets.get(e.originalUri));
|
|
74
|
+
let t = e.originalUri;
|
|
75
|
+
this.assets.has(t) || this.assets.set(t, e);
|
|
76
|
+
});
|
|
77
|
+
} catch (e) {
|
|
78
|
+
console.error("Error scanning TypeScript files:", e);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async readExistingAssetsFile() {
|
|
82
|
+
try {
|
|
83
|
+
return await v.readFile(this.options.outputFile, "utf-8");
|
|
84
|
+
} catch (e) {
|
|
85
|
+
if (e.code === "ENOENT") return "";
|
|
86
|
+
throw new E("Unable to read assets.json: " + String(e));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
sidecarPath() {
|
|
90
|
+
return y.resolve(this.options.srcDir, "..", "assets-plan.json");
|
|
91
|
+
}
|
|
92
|
+
async parseExistingAssets() {
|
|
93
|
+
let e = await this.readExistingAssetsFile();
|
|
94
|
+
if (e.trim()) {
|
|
95
|
+
let t;
|
|
96
|
+
try {
|
|
97
|
+
t = JSON.parse(e);
|
|
98
|
+
} catch {
|
|
99
|
+
throw new E("assets: invalid JSON syntax");
|
|
100
|
+
}
|
|
101
|
+
if (d(t)) throw new E("assets: single-file asset plan is not supported");
|
|
102
|
+
if (!t || typeof t != "object" || Array.isArray(t)) throw new E("assets: URL dictionary object required");
|
|
103
|
+
this.flat = { ...t };
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
this.existingAssets = c(e);
|
|
107
|
+
} catch (e) {
|
|
108
|
+
throw new E(e instanceof Error ? e.message : "assets: invalid JSON syntax");
|
|
109
|
+
}
|
|
110
|
+
await this.readSidecar();
|
|
111
|
+
}
|
|
112
|
+
async readSidecar() {
|
|
113
|
+
let e = "";
|
|
114
|
+
try {
|
|
115
|
+
e = await v.readFile(this.sidecarPath(), "utf-8");
|
|
116
|
+
} catch (e) {
|
|
117
|
+
e.code !== "ENOENT" && console.warn("assets: unable to read assets-plan.json; continuing with the dictionary only");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (!e.trim()) return;
|
|
121
|
+
let t;
|
|
122
|
+
try {
|
|
123
|
+
t = JSON.parse(e);
|
|
124
|
+
} catch {
|
|
125
|
+
console.warn("assets: assets-plan.json is not valid JSON; continuing with the dictionary only");
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (!d(t)) {
|
|
129
|
+
console.warn("assets: assets-plan.json is not a plan; continuing with the dictionary only");
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
this.document = h(e);
|
|
134
|
+
} catch {
|
|
135
|
+
console.warn("assets: assets-plan.json could not be read; continuing with the dictionary only");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (!f(this.document)) return;
|
|
139
|
+
let n = y.resolve(this.options.srcDir, "..");
|
|
140
|
+
this.implementationPaths = new Set(Object.values(this.document.assets).filter((e) => e.implementation?.path).map((e) => y.resolve(n, e.implementation.path)));
|
|
141
|
+
}
|
|
142
|
+
isImplementationReference(e, t) {
|
|
143
|
+
if (!this.implementationPaths.size || /^[a-z][a-z0-9+.-]*:/i.test(t) || t.startsWith("//")) return !1;
|
|
144
|
+
let n = t.split(/[?#]/)[0], r = n.startsWith("@/") ? y.resolve(this.options.srcDir, n.slice(2)) : y.resolve(y.dirname(e), n);
|
|
145
|
+
return this.implementationPaths.has(r);
|
|
146
|
+
}
|
|
147
|
+
async generateAssetsFile() {
|
|
148
|
+
await this.parseExistingAssets(), await this.scanAllTsFiles();
|
|
149
|
+
let e = g(this.assets, this.existingAssets, this.flat), t = y.dirname(this.options.outputFile);
|
|
150
|
+
await v.mkdir(t, { recursive: !0 }), await v.writeFile(this.options.outputFile, e, "utf-8"), await this.generateAssetsWrapper(), m(this.assets.size, this.existingAssets, this.assets, this.options.outputFile);
|
|
151
|
+
}
|
|
152
|
+
async generateAssetsWrapper() {
|
|
153
|
+
let e = this.options.outputFile.replace(/\.json$/, ".ts"), t = `// 🍎 Auto-generated wrapper for assets.json
|
|
154
|
+
// This file handles iOS image replacement via asset-interceptor.js
|
|
155
|
+
import assetsData from "./${y.basename(this.options.outputFile)}";
|
|
156
|
+
|
|
157
|
+
// Batch process all asset URLs for potential replacements
|
|
158
|
+
// sessionStorage may contain __aippy_asset_overrides__ with multiple image mappings
|
|
159
|
+
(window as any).getReplacedAssets?.(assetsData);
|
|
160
|
+
|
|
161
|
+
export default assetsData;
|
|
162
|
+
`;
|
|
163
|
+
await v.writeFile(e, t, "utf-8"), console.log(` ✓ Generated assets wrapper: ${y.relative(process.cwd(), e)}`);
|
|
164
|
+
}
|
|
165
|
+
getAssets() {
|
|
166
|
+
return Array.from(this.assets.values());
|
|
167
|
+
}
|
|
168
|
+
async replaceUrisInFile(e, t) {
|
|
169
|
+
try {
|
|
170
|
+
let a = await this.fileCache.read(e), o = b(a, {
|
|
171
|
+
sourceType: "module",
|
|
172
|
+
plugins: [
|
|
173
|
+
"typescript",
|
|
174
|
+
"jsx",
|
|
175
|
+
"decorators-legacy"
|
|
176
|
+
]
|
|
177
|
+
}), s = !1, c = this.options.outputFile.replace(/\.json$/, ".ts"), l = p(c, this.options.srcDir), u = _(e, this.options.srcDir, this.options.outputFile), d = i(o, u), f = "assetsData", m = !1, h, g = /* @__PURE__ */ new Set();
|
|
178
|
+
w(o, {
|
|
179
|
+
Identifier: (e) => {
|
|
180
|
+
g.add(e.node.name);
|
|
181
|
+
},
|
|
182
|
+
ImportDeclaration: (e) => {
|
|
183
|
+
if (!(!u.has(e.node.source.value) || e.node.importKind === "type")) for (let t of e.node.specifiers) {
|
|
184
|
+
if (t.importKind === "type") continue;
|
|
185
|
+
let n = e.scope.getBinding(t.local.name);
|
|
186
|
+
r(t) && (f = t.local.name, m = !0, h = n);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
let x = !1;
|
|
191
|
+
if (m && w(o, { StringLiteral: (r) => {
|
|
192
|
+
!S.isImportDeclaration(r.parent) && !d(r) && !this.isImplementationReference(e, r.node.value) && t.has(n(r.node.value)) && r.scope.getBinding(f) !== h && (x = !0);
|
|
193
|
+
} }), !m && g.has(f) || x) {
|
|
194
|
+
let e = "aippyAssetsData";
|
|
195
|
+
for (let t = 2; g.has(e); t++) e = `aippyAssetsData${t}`;
|
|
196
|
+
x && h.scope.rename(f, e), f = e;
|
|
197
|
+
}
|
|
198
|
+
if (w(o, { StringLiteral: (r) => {
|
|
199
|
+
let i = r.node.value;
|
|
200
|
+
if (this.isImplementationReference(e, i) || d(r) || S.isImportDeclaration(r.parent) || S.isExportNamedDeclaration(r.parent) || S.isExportAllDeclaration(r.parent) || r.findParent((e) => S.isTSType(e.node) || S.isTSInterfaceBody(e.node))) return;
|
|
201
|
+
let a = n(i);
|
|
202
|
+
if (t.has(a)) {
|
|
203
|
+
let e = t.get(a), n = S.memberExpression(S.identifier(f), /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e) ? S.identifier(e) : S.stringLiteral(e), !/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e));
|
|
204
|
+
if ((S.isObjectProperty(r.parent) || S.isObjectMethod(r.parent) || S.isClassProperty(r.parent) || S.isClassMethod(r.parent)) && r.key === "key" && (r.parent.computed = !0), r.parent && S.isJSXAttribute(r.parent)) r.replaceWith(S.jsxExpressionContainer(n));
|
|
205
|
+
else {
|
|
206
|
+
try {
|
|
207
|
+
S.validate(r.parent, r.key, n);
|
|
208
|
+
} catch {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
r.replaceWith(n);
|
|
212
|
+
}
|
|
213
|
+
r.skip(), s = !0;
|
|
214
|
+
}
|
|
215
|
+
} }), !s) return;
|
|
216
|
+
if (!m) {
|
|
217
|
+
let e = S.importDeclaration([S.importDefaultSpecifier(S.identifier(f))], S.stringLiteral(l));
|
|
218
|
+
o.program.body.unshift(e);
|
|
219
|
+
}
|
|
220
|
+
let C = T(o, {
|
|
221
|
+
retainLines: !1,
|
|
222
|
+
comments: !0,
|
|
223
|
+
compact: !1
|
|
224
|
+
}, a);
|
|
225
|
+
await v.writeFile(e, C.code, "utf-8"), this.fileCache.invalidate(e), console.log(` ✓ Replaced URIs in ${y.relative(process.cwd(), e)}`);
|
|
226
|
+
} catch (t) {
|
|
227
|
+
if (this.isStructuredInventory()) throw t;
|
|
228
|
+
console.warn(`Warning: Failed to replace URIs in ${e}:`, t);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async replaceAllUris() {
|
|
232
|
+
let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Set();
|
|
233
|
+
for (let n of this.assets.values()) e.set(n.originalUri, n.constantName), t.add(n.filePath);
|
|
234
|
+
for (let n of t) await this.replaceUrisInFile(n, e);
|
|
235
|
+
}
|
|
236
|
+
async cleanupUnusedConstants() {
|
|
237
|
+
if (!(this.document && f(this.document))) try {
|
|
238
|
+
let e = await this.readExistingAssetsFile();
|
|
239
|
+
if (!e.trim()) return;
|
|
240
|
+
let t = /* @__PURE__ */ new Map();
|
|
241
|
+
try {
|
|
242
|
+
let n = JSON.parse(e);
|
|
243
|
+
for (let [e, r] of Object.entries(n)) typeof r == "string" && t.set(e, r);
|
|
244
|
+
} catch (e) {
|
|
245
|
+
console.warn("Warning: Failed to parse assets.json:", e);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (t.size === 0) return;
|
|
249
|
+
let n = /* @__PURE__ */ new Set(), r = await u(this.options.srcDir, [".ts", ".tsx"]);
|
|
250
|
+
for (let e of r) if (!(e.endsWith("assets.json") || e.endsWith("assets.ts"))) try {
|
|
251
|
+
let r = await this.fileCache.read(e);
|
|
252
|
+
for (let e of t.keys()) r.includes(e) && n.add(e);
|
|
253
|
+
} catch (t) {
|
|
254
|
+
console.warn(`Warning: Failed to read ${e}:`, t);
|
|
255
|
+
}
|
|
256
|
+
let i = [];
|
|
257
|
+
for (let e of t.keys()) n.has(e) || i.push(e);
|
|
258
|
+
if (i.length > 0) {
|
|
259
|
+
console.log(`🧹 Removing ${i.length} unused constant(s):`), i.forEach((e) => {
|
|
260
|
+
console.log(` - ${e}`);
|
|
261
|
+
});
|
|
262
|
+
let e = [];
|
|
263
|
+
for (let n of i) {
|
|
264
|
+
let r = t.get(n);
|
|
265
|
+
r && e.push(r);
|
|
266
|
+
}
|
|
267
|
+
for (let t of e) this.assets.delete(t);
|
|
268
|
+
} else console.log("✅ All constants are in use");
|
|
269
|
+
} catch (e) {
|
|
270
|
+
console.warn("Warning: Failed to cleanup unused constants:", e);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
async upgradeJsonImportsToTs() {
|
|
274
|
+
let e = this.options.outputFile.replace(/\.json$/, ".ts"), t = p(e, this.options.srcDir), n = await u(this.options.srcDir, [".ts", ".tsx"]), r = 0;
|
|
275
|
+
for (let i of n) if (!(i.endsWith("assets.ts") || i.endsWith("assets.json"))) try {
|
|
276
|
+
let n = await this.fileCache.read(i), a = s(i, this.options.outputFile) + ".json", o = s(i, e), c = p(this.options.outputFile, this.options.srcDir) + ".json";
|
|
277
|
+
if (!n.includes(a) && !n.includes(o) && !n.includes(c)) continue;
|
|
278
|
+
let l = b(n, {
|
|
279
|
+
sourceType: "module",
|
|
280
|
+
plugins: [
|
|
281
|
+
"typescript",
|
|
282
|
+
"jsx",
|
|
283
|
+
"decorators-legacy"
|
|
284
|
+
]
|
|
285
|
+
}), u = !1;
|
|
286
|
+
if (w(l, { ImportDeclaration: (e) => {
|
|
287
|
+
let n = e.node.source.value;
|
|
288
|
+
(n === a || n === o || n === c) && (e.node.source.value = t, u = !0);
|
|
289
|
+
} }), u) {
|
|
290
|
+
let e = T(l, {
|
|
291
|
+
retainLines: !1,
|
|
292
|
+
comments: !0,
|
|
293
|
+
compact: !1
|
|
294
|
+
}, n);
|
|
295
|
+
await v.writeFile(i, e.code, "utf-8"), this.fileCache.invalidate(i), console.log(` ✓ Upgraded import in ${y.relative(process.cwd(), i)} → ${t}`), r++;
|
|
296
|
+
}
|
|
297
|
+
} catch (e) {
|
|
298
|
+
if (this.isStructuredInventory()) throw e;
|
|
299
|
+
console.warn(`Warning: Failed to upgrade imports in ${i}:`, e);
|
|
300
|
+
}
|
|
301
|
+
r > 0 && console.log(`✅ Upgraded ${r} file(s) to use ${t}`);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
function O(e = {}) {
|
|
305
|
+
return {
|
|
306
|
+
name: "vite-plugin-asset-constants",
|
|
307
|
+
apply: "build",
|
|
308
|
+
enforce: "pre",
|
|
309
|
+
async buildStart() {
|
|
310
|
+
if (!e.devMode) return;
|
|
311
|
+
let t = new D(e);
|
|
312
|
+
try {
|
|
313
|
+
await t.generateAssetsFile();
|
|
314
|
+
let e = t.getAssets();
|
|
315
|
+
e.length > 0 && (console.log(`📦 Found ${e.length} asset references:`), e.forEach((e) => {
|
|
316
|
+
console.log(` ${e.constantName} = '${e.originalUri}' (${y.relative(process.cwd(), e.filePath)}:${e.line})`);
|
|
317
|
+
}), console.log("\n🔄 Replacing URIs with constants..."), await t.replaceAllUris(), console.log("✅ URI replacement completed!")), console.log("\n🧹 Checking for unused constants..."), await t.cleanupUnusedConstants(), await t.generateAssetsFile(), console.log("\n🔄 Upgrading assets.json imports to assets.ts..."), await t.upgradeJsonImportsToTs(), console.log("✅ Asset constants finalized!\n"), t.clearCache();
|
|
318
|
+
} catch (e) {
|
|
319
|
+
console.error("❌ Error in asset constants plugin:", e), (e instanceof E || t.isStructuredInventory()) && this.error(e instanceof Error ? e.message : String(e));
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
//#endregion
|
|
325
|
+
export { O as assetConstantsPlugin, O as default };
|
|
@@ -348,7 +348,7 @@ function A(e) {
|
|
|
348
348
|
}
|
|
349
349
|
for (let e of n.legacyPlaceholderKeys ?? []) {
|
|
350
350
|
let t = r[e];
|
|
351
|
-
(!t || t.
|
|
351
|
+
(!t || t.url) && S("invalid legacy placeholder key");
|
|
352
352
|
}
|
|
353
353
|
return n;
|
|
354
354
|
}
|
|
@@ -369,7 +369,7 @@ function j(e) {
|
|
|
369
369
|
].includes(e.trim().toLowerCase());
|
|
370
370
|
}
|
|
371
371
|
function M(e) {
|
|
372
|
-
if (!e || e.trim() !== e || /[\
|
|
372
|
+
if (!e || e.trim() !== e || /[\s\\]/u.test(e) || e.startsWith("//") || /%(?![0-9a-f]{2})/i.test(e.split("?")[0]) || /%(?![0-9a-f]{2})/i.test(e.split("#")[1] ?? "")) return !1;
|
|
373
373
|
if (!/^[a-z][a-z0-9+.-]*:/i.test(e)) {
|
|
374
374
|
if (e.split(/[?#]/, 1)[0].split("/", 1)[0].includes(":")) return !1;
|
|
375
375
|
let t = e.split(/[?#]/, 1)[0].replace(/%([0-9a-f]{2})/gi, (e, t) => String.fromCharCode(Number.parseInt(t, 16)));
|
|
@@ -391,9 +391,45 @@ function M(e) {
|
|
|
391
391
|
function N(e) {
|
|
392
392
|
return O(e) ? Object.fromEntries(Object.entries(e.assets).filter(([, e]) => e.replaceable && typeof e.url == "string" && e.url.length > 0).map(([e, t]) => [e, t.url])) : { ...e };
|
|
393
393
|
}
|
|
394
|
+
//#endregion
|
|
395
|
+
//#region src/asset-constants/generator-utils.ts
|
|
394
396
|
function P(e) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
+
if (!e || typeof e != "object" || Array.isArray(e)) return !1;
|
|
398
|
+
let t = e;
|
|
399
|
+
return typeof t.schemaVersion == "number" && !!t.assets && typeof t.assets == "object" && !Array.isArray(t.assets);
|
|
400
|
+
}
|
|
401
|
+
function F(e, t, n = {}) {
|
|
402
|
+
let r = { ...n }, i = new Set(Object.keys(r));
|
|
403
|
+
for (let [e, n] of t.entries()) i.has(n) || Object.values(r).includes(e) || (r[n] = e, i.add(n));
|
|
404
|
+
for (let t of e.values()) {
|
|
405
|
+
let e = Object.entries(r).find(([, e]) => e === t.originalUri);
|
|
406
|
+
if (e) {
|
|
407
|
+
t.constantName = e[0];
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
let n = t.constantName, a = n, o = 2;
|
|
411
|
+
for (; i.has(a);) a = `${n}_${o++}`;
|
|
412
|
+
i.add(a), t.constantName = a, r[a] = t.originalUri;
|
|
413
|
+
}
|
|
414
|
+
return JSON.stringify(r, null, 2) + "\n";
|
|
415
|
+
}
|
|
416
|
+
function I(e) {
|
|
417
|
+
let t = /* @__PURE__ */ new Map();
|
|
418
|
+
try {
|
|
419
|
+
if (!e.trim()) return t;
|
|
420
|
+
let n = JSON.parse(e);
|
|
421
|
+
if (P(n)) throw Error("assets: single-file asset plan is not supported");
|
|
422
|
+
if (!n || typeof n != "object" || Array.isArray(n)) throw Error("assets: URL dictionary object required");
|
|
423
|
+
for (let [e, r] of Object.entries(n)) typeof r == "string" && t.set(r, e);
|
|
424
|
+
t.size > 0 && console.log(`📋 Found ${t.size} existing constants in assets.json`);
|
|
425
|
+
} catch (e) {
|
|
426
|
+
throw e instanceof Error && e.message.startsWith("assets:") ? e : Error("assets: invalid JSON syntax");
|
|
427
|
+
}
|
|
428
|
+
return t;
|
|
429
|
+
}
|
|
430
|
+
function L(e, t, n, r) {
|
|
431
|
+
let i = Array.from(n.values()).filter((e) => t.has(e.originalUri)).length, a = e - i;
|
|
432
|
+
console.log(a > 0 ? `✅ Generated ${e} asset constants (${a} new, ${i} reused) in ${r}` : e > 0 ? `✅ Generated ${e} asset constants (all reused from existing) in ${r}` : "✅ No asset constants found");
|
|
397
433
|
}
|
|
398
434
|
//#endregion
|
|
399
|
-
export {
|
|
435
|
+
export { N as a, m as c, _ as d, f, c as g, u as h, I as i, y as l, l as m, P as n, O as o, d as p, L as r, A as s, F as t, v as u };
|
package/dist/index/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { extractAssetsFromContent as e, findProjectRoot as t, generateConstantName as n, isValidAsset as r, processAssetURL as i } from "../utils/index.js";
|
|
2
|
-
import {
|
|
3
|
-
import { t as o } from "../aippy-preload-
|
|
2
|
+
import { assetConstantsPlugin as a } from "../asset-constants/index.js";
|
|
3
|
+
import { t as o } from "../aippy-preload-DtngFmJ5.js";
|
|
4
4
|
import { t as s } from "../aippy-tagger-By5socAS.js";
|
|
5
5
|
export { o as aippyPreloadPlugin, s as aippyTaggerPlugin, a as assetConstantsPlugin, a as default, e as extractAssetsFromContent, t as findProjectRoot, n as generateConstantName, r as isValidAsset, i as processAssetURL };
|
package/package.json
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"artStyle": { "type": "string" },
|
|
10
10
|
"legacyInventory": { "type": "string" },
|
|
11
11
|
"legacyPlaceholderKeys": {
|
|
12
|
+
"description": "Server-owned historical flat keys without a resource URL, retained as empty wrapper values regardless of current asset type or source.",
|
|
12
13
|
"type": "array",
|
|
13
14
|
"uniqueItems": true,
|
|
14
15
|
"items": { "type": "string", "minLength": 1 }
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { extractAssetsFromContent as e } from "./utils/index.js";
|
|
2
|
-
import { d as t, i as n, o as r, r as i, t as a } from "./manifest-DQGCd9CQ.js";
|
|
3
|
-
import { promises as o } from "fs";
|
|
4
|
-
import s from "path";
|
|
5
|
-
//#region src/aippy-preload/scanner-utils.ts
|
|
6
|
-
async function c(t) {
|
|
7
|
-
let n = [], r = [s.join(process.cwd(), "index.html")];
|
|
8
|
-
for (let i of r) try {
|
|
9
|
-
let r = await o.readFile(i, "utf-8"), a = e(r, "html", t);
|
|
10
|
-
n.push(...a);
|
|
11
|
-
} catch {
|
|
12
|
-
console.warn("⚠️ No index.html found in project root");
|
|
13
|
-
}
|
|
14
|
-
return n;
|
|
15
|
-
}
|
|
16
|
-
async function l(a, c) {
|
|
17
|
-
let l = [], u = s.resolve(a, "config/assets.json"), d;
|
|
18
|
-
try {
|
|
19
|
-
let e = n(await o.readFile(u, "utf8"));
|
|
20
|
-
i(e) && (d = e);
|
|
21
|
-
} catch {}
|
|
22
|
-
let f = await t(a, [
|
|
23
|
-
".ts",
|
|
24
|
-
".tsx",
|
|
25
|
-
".js",
|
|
26
|
-
".jsx"
|
|
27
|
-
]);
|
|
28
|
-
for (let t of f) try {
|
|
29
|
-
if (d && s.resolve(t) === u.replace(/\.json$/, ".ts")) continue;
|
|
30
|
-
let n = await o.readFile(t, "utf-8"), i = e(n, "js", c);
|
|
31
|
-
d && i.some((e) => Object.hasOwn(d.assets, e)) && (i = e(r(n, t, a, u), "js", c)), l.push(...i);
|
|
32
|
-
} catch (e) {
|
|
33
|
-
console.warn(`⚠️ Failed to read JS file: ${t}`, e);
|
|
34
|
-
}
|
|
35
|
-
return l;
|
|
36
|
-
}
|
|
37
|
-
async function u(n, r) {
|
|
38
|
-
let i = [], a = await t(n, [
|
|
39
|
-
".css",
|
|
40
|
-
".scss",
|
|
41
|
-
".sass",
|
|
42
|
-
".less"
|
|
43
|
-
]);
|
|
44
|
-
for (let t of a) try {
|
|
45
|
-
let n = await o.readFile(t, "utf-8"), a = e(n, "css", r);
|
|
46
|
-
i.push(...a);
|
|
47
|
-
} catch (e) {
|
|
48
|
-
console.warn(`⚠️ Failed to read CSS file: ${t}`, e);
|
|
49
|
-
}
|
|
50
|
-
return i;
|
|
51
|
-
}
|
|
52
|
-
async function d(r, c) {
|
|
53
|
-
let l = [], u = await t(r, [".json"]);
|
|
54
|
-
for (let t of u) try {
|
|
55
|
-
let r = await o.readFile(t, "utf-8");
|
|
56
|
-
if (s.basename(t) === "assets.json") {
|
|
57
|
-
let e = JSON.parse(r);
|
|
58
|
-
if (e && Object.prototype.hasOwnProperty.call(e, "schemaVersion")) {
|
|
59
|
-
let e = n(r);
|
|
60
|
-
if (i(e)) {
|
|
61
|
-
l.push(...Object.values(a(e)));
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
let u = e(r, "js", c);
|
|
67
|
-
l.push(...u);
|
|
68
|
-
} catch (e) {
|
|
69
|
-
console.warn(`⚠️ Failed to read JSON file: ${t}`, e);
|
|
70
|
-
}
|
|
71
|
-
return l;
|
|
72
|
-
}
|
|
73
|
-
async function f(e, t, n) {
|
|
74
|
-
console.log("🔍 Scanning source files for static assets...");
|
|
75
|
-
let r = [];
|
|
76
|
-
if (n) {
|
|
77
|
-
console.log("🔍 Deep scanning source file contents...");
|
|
78
|
-
let [n, i, a, o] = await Promise.all([
|
|
79
|
-
c(t),
|
|
80
|
-
l(e, t),
|
|
81
|
-
u(e, t),
|
|
82
|
-
d(e, t)
|
|
83
|
-
]);
|
|
84
|
-
r.push(...n, ...i, ...a, ...o);
|
|
85
|
-
}
|
|
86
|
-
return [...new Set(r)];
|
|
87
|
-
}
|
|
88
|
-
//#endregion
|
|
89
|
-
//#region src/aippy-preload/html-utils.ts
|
|
90
|
-
var p = "<head>", m = 6;
|
|
91
|
-
function h(e) {
|
|
92
|
-
return e.map((e) => ` <meta content="${e}" name="aippy:preload">`).join("\n");
|
|
93
|
-
}
|
|
94
|
-
function g(e, t) {
|
|
95
|
-
let n = e.indexOf(p);
|
|
96
|
-
if (n === -1) throw Error("Could not find <head> tag in HTML");
|
|
97
|
-
let r = n + m;
|
|
98
|
-
return e.slice(0, r) + "\n" + t + "\n" + e.slice(r);
|
|
99
|
-
}
|
|
100
|
-
function _(e) {
|
|
101
|
-
let t = e.length;
|
|
102
|
-
if (console.log(`📁 Found ${t} static ${t === 1 ? "asset" : "assets"} in source files`), t === 0) {
|
|
103
|
-
console.log("⚠️ No static assets found in source files.");
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
console.log(`📋 ${t === 1 ? "Asset" : "Assets"} found:`), e.forEach((e) => console.log(` - ${e}`));
|
|
107
|
-
}
|
|
108
|
-
function v(e) {
|
|
109
|
-
console.log(`✅ Injected ${e} preload meta ${e === 1 ? "tag" : "tags"} into index.html`);
|
|
110
|
-
}
|
|
111
|
-
//#endregion
|
|
112
|
-
//#region src/aippy-preload/index.ts
|
|
113
|
-
var y = 3, b = 1e3;
|
|
114
|
-
function x(e) {
|
|
115
|
-
return new Promise((t) => setTimeout(t, e));
|
|
116
|
-
}
|
|
117
|
-
async function S(e, t = y, n = b) {
|
|
118
|
-
for (let r = 1; r <= t; r++) try {
|
|
119
|
-
return await o.readFile(e, "utf-8");
|
|
120
|
-
} catch (e) {
|
|
121
|
-
if (e.code === "ENOENT") {
|
|
122
|
-
if (r < t) {
|
|
123
|
-
console.log(`⏳ index.html not found, waiting ${n}ms before retry (attempt ${r}/${t})...`), await x(n);
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
return console.log(`⚠️ index.html not found after ${t} attempts, skipping preload injection.`), null;
|
|
127
|
-
}
|
|
128
|
-
return console.error("❌ Error reading index.html:", e), null;
|
|
129
|
-
}
|
|
130
|
-
return null;
|
|
131
|
-
}
|
|
132
|
-
function C(e = {}) {
|
|
133
|
-
let t = {
|
|
134
|
-
extensions: [
|
|
135
|
-
".png",
|
|
136
|
-
".jpg",
|
|
137
|
-
".jpeg",
|
|
138
|
-
".gif",
|
|
139
|
-
".svg",
|
|
140
|
-
".mp4",
|
|
141
|
-
".mp3",
|
|
142
|
-
".wav",
|
|
143
|
-
".ogg",
|
|
144
|
-
".webm"
|
|
145
|
-
],
|
|
146
|
-
srcDir: "src",
|
|
147
|
-
outDir: "dist",
|
|
148
|
-
deepScan: !0,
|
|
149
|
-
...e
|
|
150
|
-
};
|
|
151
|
-
return {
|
|
152
|
-
name: "vite-plugin-aippy-preload",
|
|
153
|
-
apply: "build",
|
|
154
|
-
enforce: "post",
|
|
155
|
-
async writeBundle() {
|
|
156
|
-
try {
|
|
157
|
-
let e = await f(t.srcDir, t.extensions, t.deepScan);
|
|
158
|
-
if (_(e), e.length === 0) return;
|
|
159
|
-
let n = s.join(t.outDir, "index.html"), r = await S(n);
|
|
160
|
-
if (r === null) return;
|
|
161
|
-
let i = g(r, h(e));
|
|
162
|
-
await o.writeFile(n, i, "utf-8"), v(e.length);
|
|
163
|
-
} catch (e) {
|
|
164
|
-
console.error("❌ Error in aippy preload plugin:", e);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
//#endregion
|
|
170
|
-
export { C as t };
|
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
import { extractAssetsFromContent as e, generateConstantName as t, processAssetURL as n } from "./utils/index.js";
|
|
2
|
-
import { a as r, c as i, d as a, f as o, i as s, l as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h } from "./manifest-DQGCd9CQ.js";
|
|
3
|
-
import { promises as g } from "fs";
|
|
4
|
-
import _ from "path";
|
|
5
|
-
import { parse as v } from "@babel/parser";
|
|
6
|
-
import y from "@babel/traverse";
|
|
7
|
-
import * as b from "@babel/types";
|
|
8
|
-
import x from "@babel/generator";
|
|
9
|
-
//#region src/asset-constants/generator-utils.ts
|
|
10
|
-
function S(e, t, n) {
|
|
11
|
-
if (n && f(n)) {
|
|
12
|
-
let t = structuredClone(n), r = new Set(Object.keys(t.assets));
|
|
13
|
-
for (let n of e.values()) {
|
|
14
|
-
let e = Object.keys(t.assets).filter((e) => t.assets[e].url === n.originalUri);
|
|
15
|
-
if (e.length) {
|
|
16
|
-
n.constantName = e[0];
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
let i = n.constantName, a = i, o = 2;
|
|
20
|
-
for (; r.has(a);) a = `${i}_${o++}`;
|
|
21
|
-
r.add(a), n.constantName = a, t.assets[a] = {
|
|
22
|
-
type: l(n.originalUri),
|
|
23
|
-
source: "existing",
|
|
24
|
-
replaceable: !0,
|
|
25
|
-
description: `Existing asset ${a}`,
|
|
26
|
-
status: "ready",
|
|
27
|
-
url: n.originalUri
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
return JSON.stringify(t, null, 2) + "\n";
|
|
31
|
-
}
|
|
32
|
-
let r = {};
|
|
33
|
-
for (let [e, n] of t.entries()) r[n] = e;
|
|
34
|
-
return Array.from(e.values()).forEach((e) => {
|
|
35
|
-
r[e.constantName] = e.originalUri;
|
|
36
|
-
}), JSON.stringify(r, null, 2) + "\n";
|
|
37
|
-
}
|
|
38
|
-
function C(e) {
|
|
39
|
-
let t = /* @__PURE__ */ new Map();
|
|
40
|
-
try {
|
|
41
|
-
if (!e.trim()) return t;
|
|
42
|
-
let n = JSON.parse(e);
|
|
43
|
-
for (let [e, r] of Object.entries(n)) typeof r == "string" && t.set(r, e);
|
|
44
|
-
t.size > 0 && console.log(`📋 Found ${t.size} existing constants in assets.json`);
|
|
45
|
-
} catch (e) {
|
|
46
|
-
console.warn("Warning: Failed to parse existing assets.json:", e);
|
|
47
|
-
}
|
|
48
|
-
return t;
|
|
49
|
-
}
|
|
50
|
-
function w(e, t, n, r) {
|
|
51
|
-
let i = Array.from(n.values()).filter((e) => t.has(e.originalUri)).length, a = e - i;
|
|
52
|
-
console.log(a > 0 ? `✅ Generated ${e} asset constants (${a} new, ${i} reused) in ${r}` : e > 0 ? `✅ Generated ${e} asset constants (all reused from existing) in ${r}` : "✅ No asset constants found");
|
|
53
|
-
}
|
|
54
|
-
//#endregion
|
|
55
|
-
//#region src/asset-constants/index.ts
|
|
56
|
-
var T = typeof y == "function" ? y : y.default, E = typeof x == "function" ? x : x.default, D = class extends Error {}, O = class {
|
|
57
|
-
isStructuredInventory() {
|
|
58
|
-
return this.document !== void 0 && f(this.document);
|
|
59
|
-
}
|
|
60
|
-
constructor(e = {}) {
|
|
61
|
-
d(this, "options", void 0), d(this, "assets", /* @__PURE__ */ new Map()), d(this, "existingAssets", /* @__PURE__ */ new Map()), d(this, "fileCache", new c()), d(this, "document", void 0), d(this, "implementationPaths", /* @__PURE__ */ new Set()), this.options = {
|
|
62
|
-
extensions: [
|
|
63
|
-
".png",
|
|
64
|
-
".jpg",
|
|
65
|
-
".jpeg",
|
|
66
|
-
".gif",
|
|
67
|
-
".svg",
|
|
68
|
-
".mp4",
|
|
69
|
-
".mp3",
|
|
70
|
-
".wav",
|
|
71
|
-
".ogg",
|
|
72
|
-
".webm"
|
|
73
|
-
],
|
|
74
|
-
srcDir: "src",
|
|
75
|
-
outputFile: "src/config/assets.json",
|
|
76
|
-
devMode: !1,
|
|
77
|
-
...e
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
clearCache() {
|
|
81
|
-
this.fileCache.clear();
|
|
82
|
-
}
|
|
83
|
-
generateConstantName(e) {
|
|
84
|
-
let n = /* @__PURE__ */ new Set([
|
|
85
|
-
...Array.from(this.assets.values()).map((e) => e.constantName),
|
|
86
|
-
...Array.from(this.existingAssets.values()),
|
|
87
|
-
...this.document && f(this.document) ? Object.keys(this.document.assets) : []
|
|
88
|
-
]);
|
|
89
|
-
return t(e, n);
|
|
90
|
-
}
|
|
91
|
-
async scanTsFile(t) {
|
|
92
|
-
try {
|
|
93
|
-
let n = await this.fileCache.read(t), r = [], i = e(n, "js", this.options.extensions), a = this.document;
|
|
94
|
-
if (a && f(a) && i.some((e) => Object.hasOwn(a.assets, e))) {
|
|
95
|
-
let r = u(n, t, this.options.srcDir, this.options.outputFile);
|
|
96
|
-
i = e(r, "js", this.options.extensions);
|
|
97
|
-
}
|
|
98
|
-
let o = n.split("\n");
|
|
99
|
-
return i.forEach((e) => {
|
|
100
|
-
if (this.isImplementationReference(t, e)) return;
|
|
101
|
-
let n = this.generateConstantName(e), i = o.findIndex((t) => t.includes(e)) + 1;
|
|
102
|
-
r.push({
|
|
103
|
-
originalUri: e,
|
|
104
|
-
constantName: n,
|
|
105
|
-
filePath: t,
|
|
106
|
-
line: i,
|
|
107
|
-
column: 1
|
|
108
|
-
});
|
|
109
|
-
}), r;
|
|
110
|
-
} catch (e) {
|
|
111
|
-
return console.warn(`Warning: Failed to scan ${t}:`, e), [];
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
async scanAllTsFiles() {
|
|
115
|
-
let e = this.options.srcDir;
|
|
116
|
-
try {
|
|
117
|
-
let t = await a(e, [".ts", ".tsx"]);
|
|
118
|
-
for (let e of t) e.endsWith("assets.json") || e.endsWith("assets.ts") || (await this.scanTsFile(e)).forEach((e) => {
|
|
119
|
-
this.existingAssets.has(e.originalUri) && (e.constantName = this.existingAssets.get(e.originalUri));
|
|
120
|
-
let t = e.originalUri;
|
|
121
|
-
this.assets.has(t) || this.assets.set(t, e);
|
|
122
|
-
});
|
|
123
|
-
} catch (e) {
|
|
124
|
-
console.error("Error scanning TypeScript files:", e);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
async readExistingAssetsFile() {
|
|
128
|
-
try {
|
|
129
|
-
return await g.readFile(this.options.outputFile, "utf-8");
|
|
130
|
-
} catch (e) {
|
|
131
|
-
if (e.code === "ENOENT") return "";
|
|
132
|
-
throw new D("Unable to read assets.json: " + String(e));
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
async parseExistingAssets() {
|
|
136
|
-
let e = await this.readExistingAssetsFile();
|
|
137
|
-
if (e.trim()) {
|
|
138
|
-
let t;
|
|
139
|
-
try {
|
|
140
|
-
t = JSON.parse(e);
|
|
141
|
-
} catch {
|
|
142
|
-
if (/"schemaVersion(?:["\s:]|$)/i.test(e.replace(/\\u([0-9a-f]{4})/gi, (e, t) => String.fromCharCode(parseInt(t, 16))))) throw new D("assets: invalid JSON syntax");
|
|
143
|
-
}
|
|
144
|
-
if (t && Object.prototype.hasOwnProperty.call(t, "schemaVersion")) {
|
|
145
|
-
try {
|
|
146
|
-
this.document = s(e);
|
|
147
|
-
} catch (e) {
|
|
148
|
-
throw new D(e instanceof Error ? e.message : "Invalid asset manifest");
|
|
149
|
-
}
|
|
150
|
-
this.existingAssets = /* @__PURE__ */ new Map();
|
|
151
|
-
for (let [e, t] of Object.entries(m(this.document))) this.existingAssets.has(t) || this.existingAssets.set(t, e);
|
|
152
|
-
if (f(this.document)) {
|
|
153
|
-
let e = _.dirname(_.resolve(this.options.srcDir));
|
|
154
|
-
this.implementationPaths = new Set(Object.values(this.document.assets).filter((e) => (e.source === "code" || e.source === "generated") && e.implementation?.path).map((t) => _.resolve(e, t.implementation.path)));
|
|
155
|
-
}
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
this.existingAssets = C(e);
|
|
160
|
-
}
|
|
161
|
-
isImplementationReference(e, t) {
|
|
162
|
-
if (!this.implementationPaths.size || /^[a-z][a-z0-9+.-]*:/i.test(t) || t.startsWith("//")) return !1;
|
|
163
|
-
let n = t.split(/[?#]/)[0], r = n.startsWith("@/") ? _.resolve(this.options.srcDir, n.slice(2)) : _.resolve(_.dirname(e), n);
|
|
164
|
-
return this.implementationPaths.has(r);
|
|
165
|
-
}
|
|
166
|
-
async generateAssetsFile() {
|
|
167
|
-
await this.parseExistingAssets(), await this.scanAllTsFiles();
|
|
168
|
-
let e = S(this.assets, this.existingAssets, this.document), t = _.dirname(this.options.outputFile);
|
|
169
|
-
if (await g.mkdir(t, { recursive: !0 }), this.document && f(this.document)) try {
|
|
170
|
-
this.document = s(e);
|
|
171
|
-
} catch (e) {
|
|
172
|
-
throw new D(e instanceof Error ? e.message : "Invalid supplementary asset");
|
|
173
|
-
}
|
|
174
|
-
await g.writeFile(this.options.outputFile, e, "utf-8"), await this.generateAssetsWrapper(), w(this.assets.size, this.existingAssets, this.assets, this.options.outputFile);
|
|
175
|
-
}
|
|
176
|
-
async generateAssetsWrapper() {
|
|
177
|
-
let e = this.options.outputFile.replace(/\.json$/, ".ts"), t = _.basename(this.options.outputFile), n = `// 🍎 Auto-generated wrapper for assets.json
|
|
178
|
-
// This file handles iOS image replacement via asset-interceptor.js
|
|
179
|
-
import assetsData from "./${t}";
|
|
180
|
-
|
|
181
|
-
// Batch process all asset URLs for potential replacements
|
|
182
|
-
// sessionStorage may contain __aippy_asset_overrides__ with multiple image mappings
|
|
183
|
-
(window as any).getReplacedAssets?.(assetsData);
|
|
184
|
-
|
|
185
|
-
export default assetsData;
|
|
186
|
-
`;
|
|
187
|
-
if (this.document && f(this.document)) {
|
|
188
|
-
let e = [.../* @__PURE__ */ new Set([...Object.keys(m(this.document)), ...this.document.legacyPlaceholderKeys ?? []])];
|
|
189
|
-
n = `// Auto-generated asset URL map. Planning metadata stays in assets.json.
|
|
190
|
-
import manifest from "./${t}";
|
|
191
|
-
const entries = manifest.assets as Record<string, { url?: string; [field: string]: unknown }>;
|
|
192
|
-
const keys = ${JSON.stringify(e)} as const;
|
|
193
|
-
const assetsData = ${e.length ? "Object.fromEntries(keys.map(name => [name, entries[name]?.url ?? \"\"]))" : "{}"} as { [K in typeof keys[number]]: string };
|
|
194
|
-
(window as any).getReplacedAssets?.(assetsData);
|
|
195
|
-
export default assetsData;
|
|
196
|
-
`;
|
|
197
|
-
}
|
|
198
|
-
await g.writeFile(e, n, "utf-8"), console.log(` ✓ Generated assets wrapper: ${_.relative(process.cwd(), e)}`);
|
|
199
|
-
}
|
|
200
|
-
getAssets() {
|
|
201
|
-
return Array.from(this.assets.values());
|
|
202
|
-
}
|
|
203
|
-
async replaceUrisInFile(e, t) {
|
|
204
|
-
try {
|
|
205
|
-
let a = await this.fileCache.read(e), o = v(a, {
|
|
206
|
-
sourceType: "module",
|
|
207
|
-
plugins: [
|
|
208
|
-
"typescript",
|
|
209
|
-
"jsx",
|
|
210
|
-
"decorators-legacy"
|
|
211
|
-
]
|
|
212
|
-
}), s = !1, c = this.options.outputFile.replace(/\.json$/, ".ts"), l = h(c, this.options.srcDir), u = p(e, this.options.srcDir, this.options.outputFile), d = i(o, u), f = "assetsData", m = !1, y, x = /* @__PURE__ */ new Set();
|
|
213
|
-
T(o, {
|
|
214
|
-
Identifier: (e) => {
|
|
215
|
-
x.add(e.node.name);
|
|
216
|
-
},
|
|
217
|
-
ImportDeclaration: (e) => {
|
|
218
|
-
if (!(!u.has(e.node.source.value) || e.node.importKind === "type")) for (let t of e.node.specifiers) {
|
|
219
|
-
if (t.importKind === "type") continue;
|
|
220
|
-
let n = e.scope.getBinding(t.local.name);
|
|
221
|
-
r(t) && (f = t.local.name, m = !0, y = n);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
let S = !1;
|
|
226
|
-
if (m && T(o, { StringLiteral: (r) => {
|
|
227
|
-
!b.isImportDeclaration(r.parent) && !d(r) && !this.isImplementationReference(e, r.node.value) && t.has(n(r.node.value)) && r.scope.getBinding(f) !== y && (S = !0);
|
|
228
|
-
} }), !m && x.has(f) || S) {
|
|
229
|
-
let e = "aippyAssetsData";
|
|
230
|
-
for (let t = 2; x.has(e); t++) e = `aippyAssetsData${t}`;
|
|
231
|
-
S && y.scope.rename(f, e), f = e;
|
|
232
|
-
}
|
|
233
|
-
if (T(o, { StringLiteral: (r) => {
|
|
234
|
-
let i = r.node.value;
|
|
235
|
-
if (this.isImplementationReference(e, i) || d(r) || b.isImportDeclaration(r.parent) || b.isExportNamedDeclaration(r.parent) || b.isExportAllDeclaration(r.parent) || r.findParent((e) => b.isTSType(e.node) || b.isTSInterfaceBody(e.node))) return;
|
|
236
|
-
let a = n(i);
|
|
237
|
-
if (t.has(a)) {
|
|
238
|
-
let e = t.get(a), n = b.memberExpression(b.identifier(f), /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e) ? b.identifier(e) : b.stringLiteral(e), !/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e));
|
|
239
|
-
if ((b.isObjectProperty(r.parent) || b.isObjectMethod(r.parent) || b.isClassProperty(r.parent) || b.isClassMethod(r.parent)) && r.key === "key" && (r.parent.computed = !0), r.parent && b.isJSXAttribute(r.parent)) r.replaceWith(b.jsxExpressionContainer(n));
|
|
240
|
-
else {
|
|
241
|
-
try {
|
|
242
|
-
b.validate(r.parent, r.key, n);
|
|
243
|
-
} catch {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
r.replaceWith(n);
|
|
247
|
-
}
|
|
248
|
-
r.skip(), s = !0;
|
|
249
|
-
}
|
|
250
|
-
} }), !s) return;
|
|
251
|
-
if (!m) {
|
|
252
|
-
let e = b.importDeclaration([b.importDefaultSpecifier(b.identifier(f))], b.stringLiteral(l));
|
|
253
|
-
o.program.body.unshift(e);
|
|
254
|
-
}
|
|
255
|
-
let C = E(o, {
|
|
256
|
-
retainLines: !1,
|
|
257
|
-
comments: !0,
|
|
258
|
-
compact: !1
|
|
259
|
-
}, a);
|
|
260
|
-
await g.writeFile(e, C.code, "utf-8"), this.fileCache.invalidate(e), console.log(` ✓ Replaced URIs in ${_.relative(process.cwd(), e)}`);
|
|
261
|
-
} catch (t) {
|
|
262
|
-
if (this.isStructuredInventory()) throw t;
|
|
263
|
-
console.warn(`Warning: Failed to replace URIs in ${e}:`, t);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
async replaceAllUris() {
|
|
267
|
-
let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Set();
|
|
268
|
-
for (let n of this.assets.values()) e.set(n.originalUri, n.constantName), t.add(n.filePath);
|
|
269
|
-
for (let n of t) await this.replaceUrisInFile(n, e);
|
|
270
|
-
}
|
|
271
|
-
async cleanupUnusedConstants() {
|
|
272
|
-
if (!(this.document && f(this.document))) try {
|
|
273
|
-
let e = await this.readExistingAssetsFile();
|
|
274
|
-
if (!e.trim()) return;
|
|
275
|
-
let t = /* @__PURE__ */ new Map();
|
|
276
|
-
try {
|
|
277
|
-
let n = JSON.parse(e);
|
|
278
|
-
for (let [e, r] of Object.entries(n)) typeof r == "string" && t.set(e, r);
|
|
279
|
-
} catch (e) {
|
|
280
|
-
console.warn("Warning: Failed to parse assets.json:", e);
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
if (t.size === 0) return;
|
|
284
|
-
let n = /* @__PURE__ */ new Set(), r = await a(this.options.srcDir, [".ts", ".tsx"]);
|
|
285
|
-
for (let e of r) if (!(e.endsWith("assets.json") || e.endsWith("assets.ts"))) try {
|
|
286
|
-
let r = await this.fileCache.read(e);
|
|
287
|
-
for (let e of t.keys()) r.includes(e) && n.add(e);
|
|
288
|
-
} catch (t) {
|
|
289
|
-
console.warn(`Warning: Failed to read ${e}:`, t);
|
|
290
|
-
}
|
|
291
|
-
let i = [];
|
|
292
|
-
for (let e of t.keys()) n.has(e) || i.push(e);
|
|
293
|
-
if (i.length > 0) {
|
|
294
|
-
console.log(`🧹 Removing ${i.length} unused constant(s):`), i.forEach((e) => {
|
|
295
|
-
console.log(` - ${e}`);
|
|
296
|
-
});
|
|
297
|
-
let e = [];
|
|
298
|
-
for (let n of i) {
|
|
299
|
-
let r = t.get(n);
|
|
300
|
-
r && e.push(r);
|
|
301
|
-
}
|
|
302
|
-
for (let t of e) this.assets.delete(t);
|
|
303
|
-
} else console.log("✅ All constants are in use");
|
|
304
|
-
} catch (e) {
|
|
305
|
-
console.warn("Warning: Failed to cleanup unused constants:", e);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
async upgradeJsonImportsToTs() {
|
|
309
|
-
let e = this.options.outputFile.replace(/\.json$/, ".ts"), t = h(e, this.options.srcDir), n = await a(this.options.srcDir, [".ts", ".tsx"]), r = 0;
|
|
310
|
-
for (let i of n) if (!(i.endsWith("assets.ts") || i.endsWith("assets.json"))) try {
|
|
311
|
-
let n = await this.fileCache.read(i), a = o(i, this.options.outputFile) + ".json", s = o(i, e), c = h(this.options.outputFile, this.options.srcDir) + ".json";
|
|
312
|
-
if (!n.includes(a) && !n.includes(s) && !n.includes(c)) continue;
|
|
313
|
-
let l = v(n, {
|
|
314
|
-
sourceType: "module",
|
|
315
|
-
plugins: [
|
|
316
|
-
"typescript",
|
|
317
|
-
"jsx",
|
|
318
|
-
"decorators-legacy"
|
|
319
|
-
]
|
|
320
|
-
}), u = !1;
|
|
321
|
-
if (T(l, { ImportDeclaration: (e) => {
|
|
322
|
-
let n = e.node.source.value;
|
|
323
|
-
(n === a || n === s || n === c) && (e.node.source.value = t, u = !0);
|
|
324
|
-
} }), u) {
|
|
325
|
-
let e = E(l, {
|
|
326
|
-
retainLines: !1,
|
|
327
|
-
comments: !0,
|
|
328
|
-
compact: !1
|
|
329
|
-
}, n);
|
|
330
|
-
await g.writeFile(i, e.code, "utf-8"), this.fileCache.invalidate(i), console.log(` ✓ Upgraded import in ${_.relative(process.cwd(), i)} → ${t}`), r++;
|
|
331
|
-
}
|
|
332
|
-
} catch (e) {
|
|
333
|
-
if (this.isStructuredInventory()) throw e;
|
|
334
|
-
console.warn(`Warning: Failed to upgrade imports in ${i}:`, e);
|
|
335
|
-
}
|
|
336
|
-
r > 0 && console.log(`✅ Upgraded ${r} file(s) to use ${t}`);
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
function k(e = {}) {
|
|
340
|
-
return {
|
|
341
|
-
name: "vite-plugin-asset-constants",
|
|
342
|
-
apply: "build",
|
|
343
|
-
enforce: "pre",
|
|
344
|
-
async buildStart() {
|
|
345
|
-
if (!e.devMode) return;
|
|
346
|
-
let t = new O(e);
|
|
347
|
-
try {
|
|
348
|
-
await t.generateAssetsFile();
|
|
349
|
-
let e = t.getAssets();
|
|
350
|
-
e.length > 0 && (console.log(`📦 Found ${e.length} asset references:`), e.forEach((e) => {
|
|
351
|
-
console.log(` ${e.constantName} = '${e.originalUri}' (${_.relative(process.cwd(), e.filePath)}:${e.line})`);
|
|
352
|
-
}), console.log("\n🔄 Replacing URIs with constants..."), await t.replaceAllUris(), console.log("✅ URI replacement completed!")), console.log("\n🧹 Checking for unused constants..."), await t.cleanupUnusedConstants(), await t.generateAssetsFile(), console.log("\n🔄 Upgrading assets.json imports to assets.ts..."), await t.upgradeJsonImportsToTs(), console.log("✅ Asset constants finalized!\n"), t.clearCache();
|
|
353
|
-
} catch (e) {
|
|
354
|
-
console.error("❌ Error in asset constants plugin:", e), (e instanceof D || t.isStructuredInventory()) && this.error(e instanceof Error ? e.message : String(e));
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
//#endregion
|
|
360
|
-
export { k as t };
|