@hybridly/vite 0.3.0 → 0.4.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/dist/index.cjs +224 -315
- package/dist/index.d.ts +5 -15
- package/dist/index.mjs +217 -306
- package/package.json +11 -11
package/dist/index.mjs
CHANGED
|
@@ -1,35 +1,178 @@
|
|
|
1
|
-
import { resolveLayoutsDirectory, loadHybridlyConfig } from '@hybridly/config';
|
|
2
1
|
import laravel from 'laravel-vite-plugin';
|
|
3
2
|
import path from 'node:path';
|
|
4
|
-
import
|
|
3
|
+
import fs from 'node:fs';
|
|
5
4
|
import makeDebugger from 'debug';
|
|
6
5
|
import { isPackageExists } from 'local-pkg';
|
|
7
|
-
import fs from 'node:fs';
|
|
8
|
-
import { debounce } from 'throttle-debounce';
|
|
9
|
-
import { exec } from 'node:child_process';
|
|
10
6
|
import { promisify } from 'node:util';
|
|
7
|
+
import { exec } from 'node:child_process';
|
|
11
8
|
import run from 'vite-plugin-run';
|
|
12
9
|
import { merge } from '@hybridly/utils';
|
|
13
10
|
import autoimport from 'unplugin-auto-import/vite';
|
|
14
11
|
import vueComponents from 'unplugin-vue-components/vite';
|
|
15
12
|
import { HeadlessUiResolver } from 'unplugin-vue-components/resolvers';
|
|
16
13
|
import iconsResolver from 'unplugin-icons/resolver';
|
|
17
|
-
import glob from 'fast-glob';
|
|
18
14
|
import icons from 'unplugin-icons/vite';
|
|
19
15
|
import { FileSystemIconLoader } from 'unplugin-icons/loaders';
|
|
20
16
|
import vue from '@vitejs/plugin-vue';
|
|
21
17
|
|
|
22
|
-
const ROUTING_PLUGIN_NAME = "vite:hybridly:routing";
|
|
23
|
-
const ROUTING_HMR_UPDATE_ROUTING = "hybridly:routing:update";
|
|
24
|
-
const ROUTING_HMR_QUERY_UPDATE_ROUTING = "hybridly:routing:pls-update";
|
|
25
|
-
const ROUTING_VIRTUAL_MODULE_ID = "virtual:hybridly/router";
|
|
26
|
-
const RESOLVED_ROUTING_VIRTUAL_MODULE_ID = `\0${ROUTING_VIRTUAL_MODULE_ID}`;
|
|
27
18
|
const LAYOUT_PLUGIN_NAME = "vite:hybridly:layout";
|
|
28
19
|
const CONFIG_PLUGIN_NAME = "vite:hybridly:config";
|
|
29
20
|
const CONFIG_VIRTUAL_MODULE_ID = "virtual:hybridly/config";
|
|
30
21
|
const RESOLVED_CONFIG_VIRTUAL_MODULE_ID = `\0${CONFIG_VIRTUAL_MODULE_ID}`;
|
|
31
22
|
|
|
23
|
+
const debug = {
|
|
24
|
+
config: makeDebugger(CONFIG_PLUGIN_NAME),
|
|
25
|
+
layout: makeDebugger(LAYOUT_PLUGIN_NAME)
|
|
26
|
+
};
|
|
27
|
+
function isPackageInstalled(name, paths = [process.cwd()]) {
|
|
28
|
+
return isPackageExists(name, { paths });
|
|
29
|
+
}
|
|
30
|
+
function toKebabCase(key) {
|
|
31
|
+
const result = key.replace(/([A-Z])/g, " $1").trim();
|
|
32
|
+
return result.split(" ").join("-").toLowerCase();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function generateTsConfig(options, config) {
|
|
36
|
+
const tsconfig = {
|
|
37
|
+
compilerOptions: {
|
|
38
|
+
target: "esnext",
|
|
39
|
+
module: "esnext",
|
|
40
|
+
moduleResolution: "node",
|
|
41
|
+
strict: true,
|
|
42
|
+
jsx: "preserve",
|
|
43
|
+
sourceMap: true,
|
|
44
|
+
resolveJsonModule: true,
|
|
45
|
+
esModuleInterop: true,
|
|
46
|
+
allowSyntheticDefaultImports: true,
|
|
47
|
+
lib: [
|
|
48
|
+
"esnext",
|
|
49
|
+
"dom"
|
|
50
|
+
],
|
|
51
|
+
types: [
|
|
52
|
+
"vite/client",
|
|
53
|
+
"hybridly/client",
|
|
54
|
+
...options.icons !== false ? ["unplugin-icons/types/vue"] : []
|
|
55
|
+
],
|
|
56
|
+
baseUrl: "..",
|
|
57
|
+
paths: {
|
|
58
|
+
"#/*": [
|
|
59
|
+
".hybridly/*"
|
|
60
|
+
],
|
|
61
|
+
"~/*": [
|
|
62
|
+
"./*"
|
|
63
|
+
],
|
|
64
|
+
"@/*": [
|
|
65
|
+
`./${config.architecture.root}/*`
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
include: [
|
|
70
|
+
...config.components.views.map(({ path: path2 }) => `../${path2}`),
|
|
71
|
+
...config.components.layouts.map(({ path: path2 }) => `../${path2}`),
|
|
72
|
+
`../${config.architecture.root}/**/*`,
|
|
73
|
+
"./*"
|
|
74
|
+
],
|
|
75
|
+
exclude: [
|
|
76
|
+
"../public/**/*",
|
|
77
|
+
"../node_modules",
|
|
78
|
+
"../vendor"
|
|
79
|
+
]
|
|
80
|
+
};
|
|
81
|
+
write(JSON.stringify(tsconfig, null, 2), "tsconfig.json");
|
|
82
|
+
}
|
|
83
|
+
function generateLaravelIdeaHelper(config) {
|
|
84
|
+
const ideJson = {
|
|
85
|
+
$schema: "https://laravel-ide.com/schema/laravel-ide-v2.json",
|
|
86
|
+
completions: [
|
|
87
|
+
{
|
|
88
|
+
complete: "staticStrings",
|
|
89
|
+
options: {
|
|
90
|
+
strings: config.components.views.map(({ identifier }) => identifier)
|
|
91
|
+
},
|
|
92
|
+
condition: [
|
|
93
|
+
{
|
|
94
|
+
functionNames: ["hybridly"],
|
|
95
|
+
parameters: [1]
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
};
|
|
101
|
+
write(JSON.stringify(ideJson, null, 2), "ide.json");
|
|
102
|
+
}
|
|
103
|
+
async function generateRouteDefinitionFile(options, config) {
|
|
104
|
+
const routing = config?.routing;
|
|
105
|
+
if (!routing) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
debug.config("Writing types for routing:", routing);
|
|
109
|
+
const routes = Object.fromEntries(Object.entries(routing.routes).map(([key, route]) => {
|
|
110
|
+
const bindings = route.bindings ? Object.fromEntries(Object.entries(route.bindings).map(([key2]) => [key2, "__key_placeholder__"])) : void 0;
|
|
111
|
+
return [key, {
|
|
112
|
+
...route.uri ? { uri: route.uri } : {},
|
|
113
|
+
...route.domain ? { domain: route.domain } : {},
|
|
114
|
+
...route.wheres ? { wheres: route.wheres } : {},
|
|
115
|
+
...route.bindings ? { bindings } : {}
|
|
116
|
+
}];
|
|
117
|
+
}));
|
|
118
|
+
const definitions = `
|
|
119
|
+
/* eslint-disable */
|
|
120
|
+
/* prettier-ignore */
|
|
121
|
+
// This file has been automatically generated by Hybridly
|
|
122
|
+
// Modifications will be discarded
|
|
123
|
+
|
|
124
|
+
declare module 'hybridly' {
|
|
125
|
+
export interface GlobalRouteCollection {
|
|
126
|
+
url: '__URL__'
|
|
127
|
+
routes: __ROUTES__
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export {}
|
|
132
|
+
`.replace("__URL__", routing?.url ?? "").replace("__ROUTES__", JSON.stringify(routes).replaceAll('"__key_placeholder__"', "any"));
|
|
133
|
+
write(definitions, "routes.d.ts");
|
|
134
|
+
}
|
|
135
|
+
function write(data, filename) {
|
|
136
|
+
const hybridlyPath = path.resolve(process.cwd(), ".hybridly");
|
|
137
|
+
if (!fs.existsSync(hybridlyPath)) {
|
|
138
|
+
fs.mkdirSync(hybridlyPath);
|
|
139
|
+
}
|
|
140
|
+
fs.writeFileSync(path.resolve(hybridlyPath, filename), data, {
|
|
141
|
+
encoding: "utf-8"
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const shell = promisify(exec);
|
|
146
|
+
async function loadConfiguration(options) {
|
|
147
|
+
try {
|
|
148
|
+
const php = options.php ?? process.env.PHP_EXECUTABLE_PATH ?? "php";
|
|
149
|
+
const { stdout } = await shell(`${php} artisan hybridly:config`);
|
|
150
|
+
return JSON.parse(stdout);
|
|
151
|
+
} catch (e) {
|
|
152
|
+
console.error("Could not load configuration from [php artisan].");
|
|
153
|
+
throw e;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function getClientCode(config) {
|
|
158
|
+
const paths = config.components.views.map(({ path }) => `"~/${path}"`).join(",");
|
|
159
|
+
return `
|
|
160
|
+
import { initializeHybridly as init } from 'hybridly/vue'
|
|
161
|
+
|
|
162
|
+
export function initializeHybridly(config) {
|
|
163
|
+
return init({
|
|
164
|
+
...${JSON.stringify(config)},
|
|
165
|
+
imported: import.meta.glob([${paths}], { eager: ${config.components.eager ?? true} }),
|
|
166
|
+
...config,
|
|
167
|
+
})
|
|
168
|
+
}
|
|
169
|
+
`;
|
|
170
|
+
}
|
|
171
|
+
|
|
32
172
|
const initialize = (options, config) => {
|
|
173
|
+
generateTsConfig(options, config);
|
|
174
|
+
generateLaravelIdeaHelper(config);
|
|
175
|
+
generateRouteDefinitionFile(options, config);
|
|
33
176
|
return {
|
|
34
177
|
name: CONFIG_PLUGIN_NAME,
|
|
35
178
|
enforce: "pre",
|
|
@@ -37,7 +180,7 @@ const initialize = (options, config) => {
|
|
|
37
180
|
return {
|
|
38
181
|
resolve: {
|
|
39
182
|
alias: {
|
|
40
|
-
"@": path.join(process.cwd(), config.root),
|
|
183
|
+
"@": path.join(process.cwd(), config.architecture.root),
|
|
41
184
|
"#": path.join(process.cwd(), ".hybridly"),
|
|
42
185
|
"~": path.join(process.cwd())
|
|
43
186
|
}
|
|
@@ -45,19 +188,36 @@ const initialize = (options, config) => {
|
|
|
45
188
|
};
|
|
46
189
|
},
|
|
47
190
|
configureServer(server) {
|
|
48
|
-
|
|
49
|
-
|
|
191
|
+
let restarting = false;
|
|
192
|
+
async function forceRestart(message) {
|
|
193
|
+
if (restarting) {
|
|
50
194
|
return;
|
|
51
195
|
}
|
|
52
|
-
|
|
196
|
+
restarting = true;
|
|
197
|
+
server.config.logger.info(`${message}: forcing a server restart.`, {
|
|
53
198
|
clear: server.config.clearScreen,
|
|
54
199
|
timestamp: true
|
|
55
200
|
});
|
|
56
|
-
server?.restart();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
201
|
+
return await server?.restart();
|
|
202
|
+
}
|
|
203
|
+
async function handleFileChange(file) {
|
|
204
|
+
if (file.endsWith("config/hybridly.php")) {
|
|
205
|
+
return await forceRestart("Configuration file changed");
|
|
206
|
+
}
|
|
207
|
+
if (/routes\/.*\.php/.test(file)) {
|
|
208
|
+
return await forceRestart("Routing changed");
|
|
209
|
+
}
|
|
210
|
+
if (/.*\.vue$/.test(file)) {
|
|
211
|
+
const updatedConfig = await loadConfiguration(options);
|
|
212
|
+
const pagesOrLayoutsChanged = didPagesOrLayoutsChange(updatedConfig, config);
|
|
213
|
+
if (pagesOrLayoutsChanged) {
|
|
214
|
+
return await forceRestart("Page or layout changed");
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
server.watcher.on("add", handleFileChange);
|
|
219
|
+
server.watcher.on("change", handleFileChange);
|
|
220
|
+
server.watcher.on("unlink", handleFileChange);
|
|
61
221
|
},
|
|
62
222
|
resolveId(id) {
|
|
63
223
|
if (id === CONFIG_VIRTUAL_MODULE_ID) {
|
|
@@ -66,60 +226,30 @@ const initialize = (options, config) => {
|
|
|
66
226
|
},
|
|
67
227
|
async load(id) {
|
|
68
228
|
if (id === RESOLVED_CONFIG_VIRTUAL_MODULE_ID) {
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
...${JSON.stringify(config)},
|
|
76
|
-
components: import.meta.glob("${config.pagesGlob}", { eager: ${config.eager ?? true} }),
|
|
77
|
-
...config,
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
`;
|
|
229
|
+
return getClientCode(config);
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
async handleHotUpdate(ctx) {
|
|
233
|
+
if (ctx.file.includes(".hybridly")) {
|
|
234
|
+
return [];
|
|
81
235
|
}
|
|
82
236
|
}
|
|
83
237
|
};
|
|
84
238
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
layout: makeDebugger(LAYOUT_PLUGIN_NAME)
|
|
89
|
-
};
|
|
90
|
-
function isPackageInstalled(name, paths = [process.cwd()]) {
|
|
91
|
-
return isPackageExists(name, { paths });
|
|
92
|
-
}
|
|
93
|
-
function toKebabCase(key) {
|
|
94
|
-
const result = key.replace(/([A-Z])/g, " $1").trim();
|
|
95
|
-
return result.split(" ").join("-").toLowerCase();
|
|
96
|
-
}
|
|
97
|
-
function getSubstringBetween(str, start, end) {
|
|
98
|
-
const startIndex = str.indexOf(start);
|
|
99
|
-
if (startIndex === -1) {
|
|
100
|
-
return;
|
|
239
|
+
function didPagesOrLayoutsChange(updatedConfig, previousConfig) {
|
|
240
|
+
if (!previousConfig) {
|
|
241
|
+
return false;
|
|
101
242
|
}
|
|
102
|
-
|
|
103
|
-
if (endIndex === -1) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
return str.substring(startIndex + start.length, endIndex);
|
|
243
|
+
return JSON.stringify(updatedConfig.components.views) !== JSON.stringify(previousConfig.components.views) || JSON.stringify(updatedConfig.components.layouts) !== JSON.stringify(previousConfig.components.layouts);
|
|
107
244
|
}
|
|
108
245
|
|
|
109
246
|
const TEMPLATE_LAYOUT_REGEX = /<template +layout(?: *= *['"]((?:[\w\/\-_,:](?:,\ )?)+)['"] *)?>/;
|
|
110
247
|
const TYPESCRIPT_REGEX = /lang=['"]ts['"]/;
|
|
111
248
|
const layout = (options, config) => {
|
|
112
249
|
const defaultLayoutName = options?.layout?.defaultLayoutName?.replace(".vue", "") ?? "default";
|
|
113
|
-
const layoutsDirectory = path.resolve(process.cwd(), config.root, config.layouts);
|
|
114
250
|
const templateRegExp = options?.layout?.templateRegExp ?? TEMPLATE_LAYOUT_REGEX;
|
|
115
|
-
const resolveLayoutPath = (layoutName) => {
|
|
116
|
-
const [domain, layout] = layoutName.includes(":") ? layoutName.split(":") : [void 0, layoutName];
|
|
117
|
-
const layoutPath = path.resolve(resolveLayoutsDirectory(config, domain), `${layout}.vue`);
|
|
118
|
-
return normalizePath(layoutPath).replaceAll("\\", "/");
|
|
119
|
-
};
|
|
120
251
|
debug.layout("Resolved options:", {
|
|
121
|
-
defaultLayoutName
|
|
122
|
-
layoutsDirectory
|
|
252
|
+
defaultLayoutName
|
|
123
253
|
});
|
|
124
254
|
return {
|
|
125
255
|
name: LAYOUT_PLUGIN_NAME,
|
|
@@ -135,7 +265,7 @@ const layout = (options, config) => {
|
|
|
135
265
|
const exports = layouts.map((_2, i) => importName(i));
|
|
136
266
|
const imports = layouts.reduce((imports2, layoutName2, i) => `
|
|
137
267
|
${imports2}
|
|
138
|
-
import ${importName(i)} from '${
|
|
268
|
+
import ${importName(i)} from '${resolveLayoutImportPath(layoutName2, config)}';
|
|
139
269
|
`, "").trim();
|
|
140
270
|
debug.layout(`Resolved layouts "${layouts.join(", ")}":`, {
|
|
141
271
|
sourceFile: id,
|
|
@@ -153,134 +283,14 @@ const layout = (options, config) => {
|
|
|
153
283
|
}
|
|
154
284
|
};
|
|
155
285
|
};
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
window.hybridly = {
|
|
161
|
-
routing: ${JSON.stringify(routing)}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (import.meta.hot) {
|
|
165
|
-
import.meta.hot.on('${ROUTING_HMR_UPDATE_ROUTING}', (routing) => {
|
|
166
|
-
window.dispatchEvent(new CustomEvent('hybridly:routing', { detail: routing }))
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
import.meta.hot.send('${ROUTING_HMR_QUERY_UPDATE_ROUTING}')
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
`;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const shell = promisify(exec);
|
|
176
|
-
async function fetchRoutingFromArtisan(options) {
|
|
177
|
-
try {
|
|
178
|
-
const php = options.php ?? "php";
|
|
179
|
-
const result = await shell(`${php} artisan hybridly:routes`);
|
|
180
|
-
const routing = JSON.parse(result.stdout);
|
|
181
|
-
write$1(options, routing);
|
|
182
|
-
return routing;
|
|
183
|
-
} catch {
|
|
286
|
+
function resolveLayoutImportPath(name, config) {
|
|
287
|
+
const { path } = config.components.layouts.find((layout) => layout.identifier === name) ?? {};
|
|
288
|
+
if (!path) {
|
|
289
|
+
throw new Error(`Layout [${name}] could not be found.`);
|
|
184
290
|
}
|
|
291
|
+
return `~/${path}`;
|
|
185
292
|
}
|
|
186
293
|
|
|
187
|
-
const write$1 = debounce(1e3, writeDefinitions, { atBegin: true });
|
|
188
|
-
async function writeDefinitions(options, routing) {
|
|
189
|
-
routing ?? (routing = await fetchRoutingFromArtisan(options));
|
|
190
|
-
if (options.dts === false || !routing) {
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
debug.router("Writing types for routing:", routing);
|
|
194
|
-
const target = path.resolve(options.dts ?? ".hybridly/routes.d.ts");
|
|
195
|
-
const routes = Object.fromEntries(Object.entries(routing.routes).map(([key, route]) => {
|
|
196
|
-
const bindings = route.bindings ? Object.fromEntries(Object.entries(route.bindings).map(([key2]) => [key2, "__key_placeholder__"])) : void 0;
|
|
197
|
-
return [key, {
|
|
198
|
-
...route.uri ? { uri: route.uri } : {},
|
|
199
|
-
...route.domain ? { domain: route.domain } : {},
|
|
200
|
-
...route.wheres ? { wheres: route.wheres } : {},
|
|
201
|
-
...route.bindings ? { bindings } : {}
|
|
202
|
-
}];
|
|
203
|
-
}));
|
|
204
|
-
const definitions = generateDefinitions().replace("__URL__", routing?.url ?? "").replace("__ROUTES__", JSON.stringify(routes).replaceAll('"__key_placeholder__"', "any"));
|
|
205
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
206
|
-
fs.writeFileSync(target, definitions, { encoding: "utf-8" });
|
|
207
|
-
}
|
|
208
|
-
function generateDefinitions() {
|
|
209
|
-
return `
|
|
210
|
-
/* eslint-disable */
|
|
211
|
-
/* prettier-ignore */
|
|
212
|
-
// This file has been automatically generated by Hybridly
|
|
213
|
-
// Modifications will be discarded
|
|
214
|
-
|
|
215
|
-
declare module 'hybridly' {
|
|
216
|
-
export interface GlobalRouteCollection {
|
|
217
|
-
url: '__URL__'
|
|
218
|
-
routes: __ROUTES__
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
export {}`;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const router = (options, config) => {
|
|
226
|
-
const resolved = {
|
|
227
|
-
php: "php",
|
|
228
|
-
dts: ".hybridly/routes.d.ts",
|
|
229
|
-
watch: [
|
|
230
|
-
/routes\/.*\.php/
|
|
231
|
-
],
|
|
232
|
-
...options
|
|
233
|
-
};
|
|
234
|
-
let routingBeforeUpdate;
|
|
235
|
-
async function sendRoutingUpdate(server, force = false) {
|
|
236
|
-
const routing = await fetchRoutingFromArtisan(resolved) ?? routingBeforeUpdate;
|
|
237
|
-
if (force || JSON.stringify(routing) !== JSON.stringify(routingBeforeUpdate)) {
|
|
238
|
-
debug.router("Updating routes via HMR:", routing);
|
|
239
|
-
server.ws.send({
|
|
240
|
-
type: "custom",
|
|
241
|
-
event: ROUTING_HMR_UPDATE_ROUTING,
|
|
242
|
-
data: routing
|
|
243
|
-
});
|
|
244
|
-
write$1(resolved);
|
|
245
|
-
routingBeforeUpdate = routing;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
return {
|
|
249
|
-
name: ROUTING_PLUGIN_NAME,
|
|
250
|
-
configureServer(server) {
|
|
251
|
-
write$1(resolved);
|
|
252
|
-
server.ws.on(ROUTING_HMR_QUERY_UPDATE_ROUTING, () => {
|
|
253
|
-
sendRoutingUpdate(server, true);
|
|
254
|
-
});
|
|
255
|
-
server.watcher.on("change", async (path) => {
|
|
256
|
-
if (!resolved.watch.some((regex) => regex.test(path))) {
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
sendRoutingUpdate(server);
|
|
260
|
-
});
|
|
261
|
-
},
|
|
262
|
-
resolveId(id) {
|
|
263
|
-
if (id === ROUTING_VIRTUAL_MODULE_ID) {
|
|
264
|
-
return RESOLVED_ROUTING_VIRTUAL_MODULE_ID;
|
|
265
|
-
}
|
|
266
|
-
},
|
|
267
|
-
async load(id) {
|
|
268
|
-
if (id === RESOLVED_ROUTING_VIRTUAL_MODULE_ID) {
|
|
269
|
-
const routing = await fetchRoutingFromArtisan(resolved);
|
|
270
|
-
return getRouterClientCode(routing);
|
|
271
|
-
}
|
|
272
|
-
},
|
|
273
|
-
async handleHotUpdate(ctx) {
|
|
274
|
-
if (typeof resolved.dts === "string" && ctx.file.endsWith(resolved.dts)) {
|
|
275
|
-
return [];
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
transform() {
|
|
279
|
-
write$1(resolved);
|
|
280
|
-
}
|
|
281
|
-
};
|
|
282
|
-
};
|
|
283
|
-
|
|
284
294
|
function getRunOptions(options) {
|
|
285
295
|
if (options.run === false) {
|
|
286
296
|
return [];
|
|
@@ -306,7 +316,7 @@ function getRunOptions(options) {
|
|
|
306
316
|
|
|
307
317
|
function getLaravelOptions(options, config) {
|
|
308
318
|
return {
|
|
309
|
-
input: `${config.root}/application/main.ts`,
|
|
319
|
+
input: `${config.architecture.root}/application/main.ts`,
|
|
310
320
|
...options.laravel ?? {}
|
|
311
321
|
};
|
|
312
322
|
}
|
|
@@ -343,12 +353,9 @@ function getAutoImportsOptions(options, config) {
|
|
|
343
353
|
vueTemplate: true,
|
|
344
354
|
dts: ".hybridly/auto-imports.d.ts",
|
|
345
355
|
dirs: [
|
|
346
|
-
`${config.root}/utils`,
|
|
347
|
-
`${config.root}/composables`,
|
|
348
|
-
...config.
|
|
349
|
-
`${config.root}/${config.domains}/**/utils`,
|
|
350
|
-
`${config.root}/${config.domains}/**/composables`
|
|
351
|
-
] : []
|
|
356
|
+
`${config.architecture.root}/utils`,
|
|
357
|
+
`${config.architecture.root}/composables`,
|
|
358
|
+
...config.components.directories.map((directory) => `${directory}/**/*.ts`)
|
|
352
359
|
],
|
|
353
360
|
imports: [
|
|
354
361
|
"vue",
|
|
@@ -384,18 +391,17 @@ function getVueComponentsOptions(options, config) {
|
|
|
384
391
|
const customCollections = Array.isArray(options.customIcons) ? options.customIcons : options.customIcons?.collections ?? [];
|
|
385
392
|
const overrideResolvers = options.overrideResolvers ? Array.isArray(options.overrideResolvers) ? options.overrideResolvers : [options.overrideResolvers] : false;
|
|
386
393
|
const hasHeadlessUI = isPackageInstalled("@headlessui/vue");
|
|
387
|
-
const isUsingDomains = config.domains !== false;
|
|
388
394
|
return merge(
|
|
389
395
|
{
|
|
390
396
|
dirs: [
|
|
391
|
-
`./${config.root}/components`
|
|
397
|
+
`./${config.architecture.root}/components`
|
|
392
398
|
],
|
|
393
399
|
directoryAsNamespace: true,
|
|
394
400
|
dts: ".hybridly/components.d.ts",
|
|
395
401
|
resolvers: overrideResolvers || [
|
|
396
402
|
...hasIcons ? [iconsResolver({ customCollections })] : [],
|
|
397
403
|
...hasHeadlessUI ? [HeadlessUiResolver({ prefix: options?.vueComponents?.headlessUiPrefix ?? "Headless" })] : [],
|
|
398
|
-
|
|
404
|
+
ProvidedComponentListResolver(config),
|
|
399
405
|
HybridlyResolver(options.vueComponents?.linkName)
|
|
400
406
|
]
|
|
401
407
|
},
|
|
@@ -403,36 +409,21 @@ function getVueComponentsOptions(options, config) {
|
|
|
403
409
|
{ overwriteArray: false }
|
|
404
410
|
);
|
|
405
411
|
}
|
|
406
|
-
function
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
if (!
|
|
414
|
-
|
|
415
|
-
}
|
|
416
|
-
const kebabPath = toKebabCase(possiblePath.replaceAll("/", "-")).replaceAll("--", "-").replace("components-", "");
|
|
417
|
-
if (kebabPath.endsWith(kebabName) && kebabName.includes(domain)) {
|
|
418
|
-
return possiblePath;
|
|
412
|
+
function ProvidedComponentListResolver(config) {
|
|
413
|
+
function resolveComponentPath(name) {
|
|
414
|
+
const kebabName = toKebabCase(name);
|
|
415
|
+
const path = config.components.components.find((view) => {
|
|
416
|
+
const identifierAsComponentName = view.identifier.replace("::", "-").replace(".", "-");
|
|
417
|
+
return identifierAsComponentName === kebabName;
|
|
418
|
+
})?.path;
|
|
419
|
+
if (!path) {
|
|
420
|
+
return;
|
|
419
421
|
}
|
|
422
|
+
return `~/${path}`;
|
|
420
423
|
}
|
|
421
|
-
}
|
|
422
|
-
function DomainComponentsResolver(config) {
|
|
423
424
|
return {
|
|
424
425
|
type: "component",
|
|
425
|
-
resolve: (name) =>
|
|
426
|
-
if (config.domains === false) {
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
return resolveComponentUsingPaths(
|
|
430
|
-
config,
|
|
431
|
-
glob.sync(`${path.resolve(process.cwd(), config.root, config.domains)}/**/*.vue`),
|
|
432
|
-
name,
|
|
433
|
-
path.resolve
|
|
434
|
-
);
|
|
435
|
-
}
|
|
426
|
+
resolve: (name) => resolveComponentPath(name)
|
|
436
427
|
};
|
|
437
428
|
}
|
|
438
429
|
|
|
@@ -444,7 +435,7 @@ function getIconsOptions(options, config) {
|
|
|
444
435
|
const customIconDirectoryName = resolved?.icons ?? "icons";
|
|
445
436
|
const customCollections = Object.fromEntries(resolved?.collections?.map((collection) => [
|
|
446
437
|
collection,
|
|
447
|
-
FileSystemIconLoader(`./${config.root}/${customIconDirectoryName}/${collection}`)
|
|
438
|
+
FileSystemIconLoader(`./${config.architecture.root}/${customIconDirectoryName}/${collection}`)
|
|
448
439
|
]) ?? []);
|
|
449
440
|
return {
|
|
450
441
|
autoInstall: true,
|
|
@@ -476,91 +467,11 @@ function getVueOptions(options) {
|
|
|
476
467
|
);
|
|
477
468
|
}
|
|
478
469
|
|
|
479
|
-
function generateTsConfig(options, config) {
|
|
480
|
-
const tsconfig = {
|
|
481
|
-
compilerOptions: {
|
|
482
|
-
target: "esnext",
|
|
483
|
-
module: "esnext",
|
|
484
|
-
moduleResolution: "node",
|
|
485
|
-
strict: true,
|
|
486
|
-
jsx: "preserve",
|
|
487
|
-
sourceMap: true,
|
|
488
|
-
resolveJsonModule: true,
|
|
489
|
-
esModuleInterop: true,
|
|
490
|
-
allowSyntheticDefaultImports: true,
|
|
491
|
-
lib: [
|
|
492
|
-
"esnext",
|
|
493
|
-
"dom"
|
|
494
|
-
],
|
|
495
|
-
types: [
|
|
496
|
-
"vite/client",
|
|
497
|
-
"hybridly/client",
|
|
498
|
-
...options.icons !== false ? ["unplugin-icons/types/vue"] : []
|
|
499
|
-
],
|
|
500
|
-
baseUrl: "..",
|
|
501
|
-
paths: {
|
|
502
|
-
"#/*": [
|
|
503
|
-
".hybridly/*"
|
|
504
|
-
],
|
|
505
|
-
"~/*": [
|
|
506
|
-
"./*"
|
|
507
|
-
],
|
|
508
|
-
"@/*": [
|
|
509
|
-
`./${config.root}/*`
|
|
510
|
-
]
|
|
511
|
-
}
|
|
512
|
-
},
|
|
513
|
-
include: [
|
|
514
|
-
`../${config.root}/**/*`,
|
|
515
|
-
"./*"
|
|
516
|
-
],
|
|
517
|
-
exclude: [
|
|
518
|
-
"../public/**/*",
|
|
519
|
-
"../node_modules",
|
|
520
|
-
"../vendor"
|
|
521
|
-
]
|
|
522
|
-
};
|
|
523
|
-
write(JSON.stringify(tsconfig, null, 2), "tsconfig.json");
|
|
524
|
-
}
|
|
525
|
-
function generateLaravelIdeaHelper(config) {
|
|
526
|
-
const ideJson = {
|
|
527
|
-
$schema: "https://laravel-ide.com/schema/laravel-ide-v2.json",
|
|
528
|
-
completions: [
|
|
529
|
-
...config.domains ? [] : [{
|
|
530
|
-
complete: "directoryFiles",
|
|
531
|
-
options: {
|
|
532
|
-
directory: `/${config.root}/${config.pages}`,
|
|
533
|
-
suffixToClear: ".vue"
|
|
534
|
-
},
|
|
535
|
-
condition: [
|
|
536
|
-
{
|
|
537
|
-
functionNames: ["hybridly"],
|
|
538
|
-
parameters: [1]
|
|
539
|
-
}
|
|
540
|
-
]
|
|
541
|
-
}]
|
|
542
|
-
]
|
|
543
|
-
};
|
|
544
|
-
write(JSON.stringify(ideJson, null, 2), "ide.json");
|
|
545
|
-
}
|
|
546
|
-
function write(data, filename) {
|
|
547
|
-
const hybridlyPath = path.resolve(process.cwd(), ".hybridly");
|
|
548
|
-
if (!fs.existsSync(hybridlyPath)) {
|
|
549
|
-
fs.mkdirSync(hybridlyPath);
|
|
550
|
-
}
|
|
551
|
-
fs.writeFileSync(path.resolve(hybridlyPath, filename), data, {
|
|
552
|
-
encoding: "utf-8"
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
|
|
556
470
|
async function plugin(options = {}) {
|
|
557
|
-
const config = await
|
|
558
|
-
generateTsConfig(options, config);
|
|
559
|
-
generateLaravelIdeaHelper(config);
|
|
471
|
+
const config = await loadConfiguration(options);
|
|
560
472
|
return [
|
|
561
473
|
initialize(options, config),
|
|
562
474
|
layout(options, config),
|
|
563
|
-
router(options),
|
|
564
475
|
options.laravel !== false && laravel(getLaravelOptions(options, config)),
|
|
565
476
|
options.run !== false && run(getRunOptions(options)),
|
|
566
477
|
options.vueComponents !== false && vueComponents(getVueComponentsOptions(options, config)),
|
|
@@ -570,4 +481,4 @@ async function plugin(options = {}) {
|
|
|
570
481
|
];
|
|
571
482
|
}
|
|
572
483
|
|
|
573
|
-
export { HybridlyImports, HybridlyResolver, plugin as default, layout
|
|
484
|
+
export { HybridlyImports, HybridlyResolver, plugin as default, layout };
|