renusify 3.1.3 → 3.1.5
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/package.json +1 -1
- package/plugins/auto-loader.mjs +223 -191
- package/plugins/trans/DateTime.js +135 -74
- package/tests/DateTime.test.js +596 -0
- package/tests/autoloader.test.js +905 -0
package/package.json
CHANGED
package/plugins/auto-loader.mjs
CHANGED
|
@@ -1,314 +1,346 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import path from
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
3
|
|
|
4
4
|
export default function renusifyAutoPlugin(options = {}) {
|
|
5
|
-
const { prefix =
|
|
5
|
+
const { prefix = "r", debug = false } = options;
|
|
6
6
|
|
|
7
7
|
const state = {
|
|
8
8
|
usedComponents: new Set(),
|
|
9
9
|
usedDirectives: new Set(),
|
|
10
10
|
componentsMap: new Map(),
|
|
11
11
|
directivesMap: new Map(),
|
|
12
|
-
rootDir:
|
|
13
|
-
}
|
|
14
|
-
|
|
12
|
+
rootDir: "",
|
|
13
|
+
};
|
|
15
14
|
|
|
16
15
|
function parseExports(filePath, exclude = []) {
|
|
17
16
|
try {
|
|
18
|
-
const content = fs.readFileSync(filePath,
|
|
17
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
19
18
|
const clean = content
|
|
20
|
-
.replace(/\/\*[\s\S]*?\*\//g,
|
|
21
|
-
.replace(/\/\/.*$/gm,
|
|
19
|
+
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
20
|
+
.replace(/\/\/.*$/gm, "");
|
|
22
21
|
|
|
23
|
-
const regex =
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const regex =
|
|
23
|
+
/export\s+\*\s+as\s+([a-zA-Z_]\w*)\s+from\s+['"]([^'"]+)['"]/g;
|
|
24
|
+
const map = new Map();
|
|
25
|
+
let m;
|
|
26
26
|
while ((m = regex.exec(clean)) !== null) {
|
|
27
|
-
const [, name, relPath] = m
|
|
28
|
-
if (exclude.includes(name)) continue
|
|
29
|
-
let p = relPath.replace(/^\.\//,
|
|
30
|
-
if (!p.match(/\.(js|vue|ts|mjs)$/)) p = `${p}/index.js
|
|
31
|
-
map.set(name, p)
|
|
27
|
+
const [, name, relPath] = m;
|
|
28
|
+
if (exclude.includes(name)) continue;
|
|
29
|
+
let p = relPath.replace(/^\.\//, "");
|
|
30
|
+
if (!p.match(/\.(js|vue|ts|mjs)$/)) p = `${p}/index.js`;
|
|
31
|
+
map.set(name, p);
|
|
32
32
|
}
|
|
33
|
-
return map
|
|
33
|
+
return map;
|
|
34
34
|
} catch (err) {
|
|
35
|
-
console.warn(`[renusify-auto] Could not parse ${filePath}:`, err.message)
|
|
36
|
-
return new Map()
|
|
35
|
+
console.warn(`[renusify-auto] Could not parse ${filePath}:`, err.message);
|
|
36
|
+
return new Map();
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
41
40
|
function kebab2camel(s) {
|
|
42
|
-
return s.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase())
|
|
41
|
+
return s.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
|
|
46
44
|
function scanFile(filePath) {
|
|
47
45
|
try {
|
|
48
|
-
const content = fs.readFileSync(filePath,
|
|
49
|
-
const tmplMatch = content.match(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const tagRe = /<\s*\/?([a-zA-Z][a-zA-Z0-9-]*)/g
|
|
55
|
-
let m
|
|
46
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
47
|
+
const tmplMatch = content.match(
|
|
48
|
+
/<template(?:\s[^>]*)?>([\s\S]*)<\/template>/,
|
|
49
|
+
);
|
|
50
|
+
if (!tmplMatch) return;
|
|
51
|
+
const tmpl = tmplMatch[1];
|
|
52
|
+
const tagRe = /<\s*\/?([a-zA-Z][a-zA-Z0-9-]*)/g;
|
|
53
|
+
let m;
|
|
56
54
|
while ((m = tagRe.exec(tmpl)) !== null) {
|
|
57
|
-
const tag = m[1]
|
|
58
|
-
if (!tag.startsWith(prefix)) continue
|
|
59
|
-
const camel = kebab2camel(tag)
|
|
60
|
-
if (state.componentsMap.has(camel)) state.usedComponents.add(camel)
|
|
61
|
-
else if (state.componentsMap.has(tag)) state.usedComponents.add(tag)
|
|
55
|
+
const tag = m[1];
|
|
56
|
+
if (!tag.startsWith(prefix)) continue;
|
|
57
|
+
const camel = kebab2camel(tag);
|
|
58
|
+
if (state.componentsMap.has(camel)) state.usedComponents.add(camel);
|
|
59
|
+
else if (state.componentsMap.has(tag)) state.usedComponents.add(tag);
|
|
62
60
|
}
|
|
63
61
|
|
|
64
|
-
const dirRe = /\bv-([a-zA-Z][a-zA-Z0-9-]*)/g
|
|
62
|
+
const dirRe = /\bv-([a-zA-Z][a-zA-Z0-9-]*)/g;
|
|
65
63
|
const builtins = new Set([
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
"model",
|
|
65
|
+
"if",
|
|
66
|
+
"else",
|
|
67
|
+
"else-if",
|
|
68
|
+
"for",
|
|
69
|
+
"show",
|
|
70
|
+
"bind",
|
|
71
|
+
"on",
|
|
72
|
+
"slot",
|
|
73
|
+
"text",
|
|
74
|
+
"html",
|
|
75
|
+
"cloak",
|
|
76
|
+
"once",
|
|
77
|
+
"memo",
|
|
78
|
+
"pre",
|
|
79
|
+
]);
|
|
69
80
|
|
|
70
81
|
while ((m = dirRe.exec(tmpl)) !== null) {
|
|
71
|
-
const d = m[1]
|
|
72
|
-
if (builtins.has(d)) continue
|
|
73
|
-
const camel = kebab2camel(d)
|
|
74
|
-
const candidates = [
|
|
82
|
+
const d = m[1];
|
|
83
|
+
if (builtins.has(d)) continue;
|
|
84
|
+
const camel = kebab2camel(d);
|
|
85
|
+
const candidates = [
|
|
86
|
+
d,
|
|
87
|
+
camel,
|
|
88
|
+
`v${camel.charAt(0).toUpperCase()}${camel.slice(1)}`,
|
|
89
|
+
];
|
|
75
90
|
for (const c of candidates) {
|
|
76
91
|
if (state.directivesMap.has(c)) {
|
|
77
|
-
state.usedDirectives.add(c)
|
|
78
|
-
break
|
|
92
|
+
state.usedDirectives.add(c);
|
|
93
|
+
break;
|
|
79
94
|
}
|
|
80
95
|
}
|
|
81
96
|
}
|
|
82
|
-
} catch {
|
|
83
|
-
|
|
97
|
+
} catch (e) {
|
|
98
|
+
console.error(e);
|
|
84
99
|
}
|
|
85
100
|
}
|
|
86
101
|
|
|
87
|
-
|
|
88
102
|
function scanDirSync(dir) {
|
|
89
|
-
let entries
|
|
103
|
+
let entries;
|
|
90
104
|
try {
|
|
91
|
-
entries = fs.readdirSync(dir, { withFileTypes: true })
|
|
105
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
92
106
|
} catch {
|
|
93
|
-
return
|
|
107
|
+
return;
|
|
94
108
|
}
|
|
95
109
|
for (const entry of entries) {
|
|
96
|
-
const full = path.join(dir, entry.name)
|
|
110
|
+
const full = path.join(dir, entry.name);
|
|
97
111
|
if (entry.isDirectory()) {
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
112
|
+
if (
|
|
113
|
+
["node_modules", "dist", ".git", ".nuxt", ".output"].includes(
|
|
114
|
+
entry.name,
|
|
115
|
+
)
|
|
116
|
+
)
|
|
117
|
+
continue;
|
|
118
|
+
scanDirSync(full);
|
|
119
|
+
} else if (entry.name.endsWith(".vue")) {
|
|
120
|
+
scanFile(full);
|
|
102
121
|
}
|
|
103
122
|
}
|
|
104
123
|
}
|
|
105
124
|
|
|
125
|
+
function generateImportStatements() {
|
|
126
|
+
const comps = [...state.usedComponents].sort();
|
|
127
|
+
const dirs = [...state.usedDirectives].sort();
|
|
128
|
+
|
|
129
|
+
if (comps.length === 0 && dirs.length === 0) return "";
|
|
106
130
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return name.charAt(1).toLowerCase() + name.slice(2)
|
|
121
|
-
}
|
|
122
|
-
return name
|
|
123
|
-
})
|
|
124
|
-
code += `import { ${dirNames.join(', ')} } from 'renusify/directive/index.js'\n`
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return code
|
|
128
|
-
}
|
|
131
|
+
let code = "\n";
|
|
132
|
+
if (comps.length > 0) {
|
|
133
|
+
code += `import {\n ${comps.join(",\n ")}\n} from 'renusify/components/index.js'\n`;
|
|
134
|
+
}
|
|
135
|
+
if (dirs.length > 0) {
|
|
136
|
+
const dirNames = dirs.map((name) => {
|
|
137
|
+
if (name.startsWith("v") || name.startsWith("V")) {
|
|
138
|
+
return name.charAt(1).toLowerCase() + name.slice(2);
|
|
139
|
+
}
|
|
140
|
+
return name;
|
|
141
|
+
});
|
|
142
|
+
code += `import { ${dirNames.join(", ")} } from 'renusify/directive/index.js'\n`;
|
|
143
|
+
}
|
|
129
144
|
|
|
145
|
+
return code;
|
|
146
|
+
}
|
|
130
147
|
|
|
131
148
|
function generateComponentsObject() {
|
|
132
|
-
const comps = [...state.usedComponents].sort()
|
|
133
|
-
if (comps.length === 0) return null
|
|
134
|
-
return `components: {\n ${comps.join(
|
|
149
|
+
const comps = [...state.usedComponents].sort();
|
|
150
|
+
if (comps.length === 0) return null;
|
|
151
|
+
return `components: {\n ${comps.join(",\n ")}\n }`;
|
|
135
152
|
}
|
|
136
153
|
|
|
137
|
-
|
|
138
154
|
function generateDirectivesObject() {
|
|
139
|
-
const dirs = [...state.usedDirectives].sort()
|
|
140
|
-
if (dirs.length === 0) return null
|
|
141
|
-
const dirNames = dirs.map(name => {
|
|
142
|
-
if (name.startsWith(
|
|
143
|
-
return name.charAt(1).toLowerCase() + name.slice(2)
|
|
155
|
+
const dirs = [...state.usedDirectives].sort();
|
|
156
|
+
if (dirs.length === 0) return null;
|
|
157
|
+
const dirNames = dirs.map((name) => {
|
|
158
|
+
if (name.startsWith("v") || name.startsWith("V")) {
|
|
159
|
+
return name.charAt(1).toLowerCase() + name.slice(2);
|
|
144
160
|
}
|
|
145
|
-
return name
|
|
146
|
-
})
|
|
147
|
-
return `directives: { ${dirNames.join(
|
|
161
|
+
return name;
|
|
162
|
+
});
|
|
163
|
+
return `directives: { ${dirNames.join(", ")} }`;
|
|
148
164
|
}
|
|
149
165
|
|
|
150
166
|
return {
|
|
151
|
-
name:
|
|
152
|
-
enforce:
|
|
167
|
+
name: "vite-plugin-renusify-auto",
|
|
168
|
+
enforce: "pre",
|
|
153
169
|
|
|
154
170
|
configResolved(config) {
|
|
155
|
-
state.rootDir = config.root
|
|
156
|
-
const renusifyPath = path.join(config.root,
|
|
171
|
+
state.rootDir = config.root;
|
|
172
|
+
const renusifyPath = path.join(config.root, "node_modules/renusify");
|
|
157
173
|
|
|
158
174
|
state.componentsMap = parseExports(
|
|
159
|
-
path.join(renusifyPath,
|
|
160
|
-
[
|
|
161
|
-
)
|
|
175
|
+
path.join(renusifyPath, "components/index.js"),
|
|
176
|
+
["_register"],
|
|
177
|
+
);
|
|
162
178
|
state.directivesMap = parseExports(
|
|
163
|
-
path.join(renusifyPath,
|
|
164
|
-
[
|
|
165
|
-
)
|
|
179
|
+
path.join(renusifyPath, "directive/index.js"),
|
|
180
|
+
["_registers"],
|
|
181
|
+
);
|
|
166
182
|
|
|
167
|
-
if (config.command ===
|
|
168
|
-
state.usedComponents = new Set(state.componentsMap.keys())
|
|
169
|
-
state.usedDirectives = new Set(state.directivesMap.keys())
|
|
183
|
+
if (config.command === "serve") {
|
|
184
|
+
state.usedComponents = new Set(state.componentsMap.keys());
|
|
185
|
+
state.usedDirectives = new Set(state.directivesMap.keys());
|
|
170
186
|
if (debug) {
|
|
171
|
-
console.log(
|
|
187
|
+
console.log(
|
|
188
|
+
`[renusify-auto] Dev mode: ALL ${state.componentsMap.size} components, ${state.directivesMap.size} directives`,
|
|
189
|
+
);
|
|
172
190
|
}
|
|
173
191
|
} else {
|
|
174
|
-
scanDirSync(path.join(config.root,
|
|
192
|
+
scanDirSync(path.join(config.root, "src"));
|
|
175
193
|
if (debug) {
|
|
176
|
-
console.log(
|
|
177
|
-
|
|
178
|
-
|
|
194
|
+
console.log(
|
|
195
|
+
`[renusify-auto] Build mode: ${state.usedComponents.size} components, ${state.usedDirectives.size} directives`,
|
|
196
|
+
);
|
|
197
|
+
console.log(" Components:", [...state.usedComponents].join(", "));
|
|
198
|
+
console.log(" Directives:", [...state.usedDirectives].join(", "));
|
|
179
199
|
}
|
|
180
200
|
}
|
|
181
201
|
},
|
|
182
202
|
|
|
183
203
|
transform(code, id) {
|
|
184
|
-
if (!/main\.(js|ts)$/.test(id)) return null
|
|
185
|
-
if (id.includes(
|
|
204
|
+
if (!/main\.(js|ts)$/.test(id)) return null;
|
|
205
|
+
if (id.includes("node_modules")) return null;
|
|
186
206
|
|
|
187
|
-
let newCode = code
|
|
188
|
-
let modified = false
|
|
207
|
+
let newCode = code;
|
|
208
|
+
let modified = false;
|
|
189
209
|
|
|
190
|
-
const importStmts = generateImportStatements()
|
|
210
|
+
const importStmts = generateImportStatements();
|
|
191
211
|
if (importStmts) {
|
|
192
|
-
const importRegex = /^import\s+[^;]+;?\s*$/gm
|
|
193
|
-
const allImports = code.match(importRegex)
|
|
194
|
-
|
|
212
|
+
const importRegex = /^import\s+[^;]+;?\s*$/gm;
|
|
213
|
+
const allImports = code.match(importRegex);
|
|
214
|
+
|
|
195
215
|
if (allImports && allImports.length > 0) {
|
|
196
|
-
const lastImport = allImports[allImports.length - 1]
|
|
197
|
-
const lastImportIndex = code.lastIndexOf(lastImport)
|
|
198
|
-
const insertPos = lastImportIndex + lastImport.length
|
|
199
|
-
newCode =
|
|
216
|
+
const lastImport = allImports[allImports.length - 1];
|
|
217
|
+
const lastImportIndex = code.lastIndexOf(lastImport);
|
|
218
|
+
const insertPos = lastImportIndex + lastImport.length;
|
|
219
|
+
newCode =
|
|
220
|
+
newCode.slice(0, insertPos) +
|
|
221
|
+
importStmts +
|
|
222
|
+
newCode.slice(insertPos);
|
|
200
223
|
} else {
|
|
201
|
-
newCode = importStmts +
|
|
224
|
+
newCode = importStmts + "\n" + newCode;
|
|
202
225
|
}
|
|
203
|
-
modified = true
|
|
226
|
+
modified = true;
|
|
204
227
|
}
|
|
205
228
|
|
|
206
|
-
const renusifyRegex = /\.use\s*\(\s*renusify\s*,\s*\{
|
|
207
|
-
const useMatch = newCode.match(renusifyRegex)
|
|
229
|
+
const renusifyRegex = /\.use\s*\(\s*renusify\s*,\s*\{/;
|
|
230
|
+
const useMatch = newCode.match(renusifyRegex);
|
|
208
231
|
|
|
209
232
|
if (useMatch) {
|
|
210
|
-
const matchIndex = useMatch.index
|
|
211
|
-
const startOfOptions = matchIndex + useMatch[0].length
|
|
233
|
+
const matchIndex = useMatch.index;
|
|
234
|
+
const startOfOptions = matchIndex + useMatch[0].length;
|
|
212
235
|
|
|
213
|
-
let braceCount = 1
|
|
214
|
-
let i = startOfOptions
|
|
236
|
+
let braceCount = 1;
|
|
237
|
+
let i = startOfOptions;
|
|
215
238
|
while (i < newCode.length && braceCount > 0) {
|
|
216
|
-
if (newCode[i] ===
|
|
217
|
-
else if (newCode[i] ===
|
|
218
|
-
if (braceCount > 0) i
|
|
239
|
+
if (newCode[i] === "{") braceCount++;
|
|
240
|
+
else if (newCode[i] === "}") braceCount--;
|
|
241
|
+
if (braceCount > 0) i++;
|
|
219
242
|
}
|
|
220
243
|
|
|
221
244
|
if (braceCount === 0) {
|
|
222
|
-
const endOfOptions = i
|
|
223
|
-
const optionsContent = newCode.slice(startOfOptions, endOfOptions)
|
|
224
|
-
let cleanedOptions = optionsContent
|
|
245
|
+
const endOfOptions = i;
|
|
246
|
+
const optionsContent = newCode.slice(startOfOptions, endOfOptions);
|
|
247
|
+
let cleanedOptions = optionsContent;
|
|
225
248
|
|
|
226
|
-
cleanedOptions = removeProperty(cleanedOptions,
|
|
227
|
-
cleanedOptions = removeProperty(cleanedOptions,
|
|
249
|
+
cleanedOptions = removeProperty(cleanedOptions, "components");
|
|
250
|
+
cleanedOptions = removeProperty(cleanedOptions, "directives");
|
|
228
251
|
|
|
229
|
-
cleanedOptions = cleanedOptions.replace(/,(\s*)}/g,
|
|
230
|
-
cleanedOptions = cleanedOptions.trim()
|
|
252
|
+
cleanedOptions = cleanedOptions.replace(/,(\s*)}/g, "$1}");
|
|
253
|
+
cleanedOptions = cleanedOptions.trim();
|
|
231
254
|
|
|
232
|
-
const componentsObj = generateComponentsObject()
|
|
233
|
-
const directivesObj = generateDirectivesObject()
|
|
255
|
+
const componentsObj = generateComponentsObject();
|
|
256
|
+
const directivesObj = generateDirectivesObject();
|
|
234
257
|
|
|
235
|
-
let newOptionsContent = cleanedOptions
|
|
258
|
+
let newOptionsContent = cleanedOptions;
|
|
236
259
|
|
|
237
260
|
if (componentsObj || directivesObj) {
|
|
238
|
-
const needsComma =
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
261
|
+
const needsComma =
|
|
262
|
+
newOptionsContent.trim().length > 0 &&
|
|
263
|
+
!newOptionsContent.trim().endsWith(",");
|
|
264
|
+
const comma = needsComma ? "," : "";
|
|
265
|
+
|
|
266
|
+
let additions = "";
|
|
267
|
+
if (componentsObj) additions += "\n " + componentsObj;
|
|
268
|
+
if (directivesObj)
|
|
269
|
+
additions += (additions ? "," : "") + "\n " + directivesObj;
|
|
244
270
|
|
|
245
271
|
if (newOptionsContent.trim().length === 0) {
|
|
246
|
-
newOptionsContent = additions +
|
|
272
|
+
newOptionsContent = additions + "\n ";
|
|
247
273
|
} else {
|
|
248
|
-
newOptionsContent =
|
|
274
|
+
newOptionsContent =
|
|
275
|
+
newOptionsContent + comma + additions + "\n ";
|
|
249
276
|
}
|
|
250
277
|
}
|
|
251
278
|
|
|
252
|
-
newCode =
|
|
253
|
-
|
|
279
|
+
newCode =
|
|
280
|
+
newCode.slice(0, startOfOptions) +
|
|
281
|
+
newOptionsContent +
|
|
282
|
+
newCode.slice(endOfOptions);
|
|
283
|
+
modified = true;
|
|
254
284
|
}
|
|
255
285
|
}
|
|
256
286
|
|
|
257
287
|
if (modified) {
|
|
258
288
|
if (debug) {
|
|
259
|
-
console.log(`[renusify-auto] Transformed ${path.basename(id)}`)
|
|
289
|
+
console.log(`[renusify-auto] Transformed ${path.basename(id)}`);
|
|
260
290
|
}
|
|
261
|
-
return { code: newCode, map: null }
|
|
291
|
+
return { code: newCode, map: null };
|
|
262
292
|
}
|
|
263
293
|
|
|
264
|
-
return null
|
|
294
|
+
return null;
|
|
265
295
|
},
|
|
266
|
-
}
|
|
296
|
+
};
|
|
267
297
|
}
|
|
268
298
|
|
|
269
299
|
function removeProperty(optionsStr, propName) {
|
|
270
|
-
const propRegex = new RegExp(`,?\\s*${propName}\\s*:\\s*`)
|
|
271
|
-
const match = propRegex.exec(optionsStr)
|
|
272
|
-
|
|
273
|
-
if (!match) return optionsStr
|
|
274
|
-
|
|
275
|
-
const startIndex = match.index
|
|
276
|
-
const valueStart = startIndex + match[0].length
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
let braceCount = 1
|
|
285
|
-
let i = valueStart + 1
|
|
300
|
+
const propRegex = new RegExp(`,?\\s*${propName}\\s*:\\s*`);
|
|
301
|
+
const match = propRegex.exec(optionsStr);
|
|
302
|
+
|
|
303
|
+
if (!match) return optionsStr;
|
|
304
|
+
|
|
305
|
+
const startIndex = match.index;
|
|
306
|
+
const valueStart = startIndex + match[0].length;
|
|
307
|
+
|
|
308
|
+
let endIndex = valueStart;
|
|
309
|
+
const firstChar = optionsStr[valueStart];
|
|
310
|
+
|
|
311
|
+
if (firstChar === "{") {
|
|
312
|
+
let braceCount = 1;
|
|
313
|
+
let i = valueStart + 1;
|
|
286
314
|
while (i < optionsStr.length && braceCount > 0) {
|
|
287
|
-
if (optionsStr[i] ===
|
|
288
|
-
else if (optionsStr[i] ===
|
|
289
|
-
i
|
|
315
|
+
if (optionsStr[i] === "{") braceCount++;
|
|
316
|
+
else if (optionsStr[i] === "}") braceCount--;
|
|
317
|
+
i++;
|
|
290
318
|
}
|
|
291
|
-
endIndex = i
|
|
292
|
-
} else if (firstChar ===
|
|
293
|
-
let bracketCount = 1
|
|
294
|
-
let i = valueStart + 1
|
|
319
|
+
endIndex = i;
|
|
320
|
+
} else if (firstChar === "[") {
|
|
321
|
+
let bracketCount = 1;
|
|
322
|
+
let i = valueStart + 1;
|
|
295
323
|
while (i < optionsStr.length && bracketCount > 0) {
|
|
296
|
-
if (optionsStr[i] ===
|
|
297
|
-
else if (optionsStr[i] ===
|
|
298
|
-
i
|
|
324
|
+
if (optionsStr[i] === "[") bracketCount++;
|
|
325
|
+
else if (optionsStr[i] === "]") bracketCount--;
|
|
326
|
+
i++;
|
|
299
327
|
}
|
|
300
|
-
endIndex = i
|
|
328
|
+
endIndex = i;
|
|
301
329
|
} else {
|
|
302
|
-
let i = valueStart
|
|
303
|
-
while (
|
|
304
|
-
i
|
|
330
|
+
let i = valueStart;
|
|
331
|
+
while (
|
|
332
|
+
i < optionsStr.length &&
|
|
333
|
+
optionsStr[i] !== "," &&
|
|
334
|
+
optionsStr[i] !== "}"
|
|
335
|
+
) {
|
|
336
|
+
i++;
|
|
305
337
|
}
|
|
306
|
-
endIndex = i
|
|
338
|
+
endIndex = i;
|
|
307
339
|
}
|
|
308
340
|
|
|
309
|
-
if (endIndex < optionsStr.length && optionsStr[endIndex] ===
|
|
310
|
-
endIndex
|
|
341
|
+
if (endIndex < optionsStr.length && optionsStr[endIndex] === ",") {
|
|
342
|
+
endIndex++;
|
|
311
343
|
}
|
|
312
344
|
|
|
313
|
-
return optionsStr.slice(0, startIndex) + optionsStr.slice(endIndex)
|
|
314
|
-
}
|
|
345
|
+
return optionsStr.slice(0, startIndex) + optionsStr.slice(endIndex);
|
|
346
|
+
}
|