zuby 1.0.79 → 1.0.81
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 +9 -0
- package/commands/add.d.ts +1 -0
- package/commands/add.js +112 -0
- package/commands/build.d.ts +1 -1
- package/commands/build.js +21 -5
- package/commands/dev.d.ts +1 -1
- package/commands/index.js +5 -0
- package/commands/info.d.ts +1 -1
- package/commands/info.js +1 -1
- package/commands/init.d.ts +2 -2
- package/commands/init.js +5 -5
- package/commands/preview.d.ts +1 -1
- package/commands/upgrade.d.ts +1 -1
- package/commands/upgrade.js +20 -6
- package/config.d.ts +1 -1
- package/config.js +7 -24
- package/contexts/globalContext.d.ts +2 -2
- package/contexts/globalContext.js +1 -1
- package/contexts/index.d.ts +4 -4
- package/contexts/index.js +0 -3
- package/contexts/pageContext.d.ts +1 -1
- package/contexts/pageContext.js +5 -5
- package/defineConfig.d.ts +1 -1
- package/examples/basic/js/components/Card/index.css +25 -25
- package/examples/basic/js/components/Card/index.jsx +11 -11
- package/examples/basic/js/components/Card/index.module.css +24 -24
- package/examples/basic/js/package.json +14 -14
- package/examples/basic/js/pages/about.jsx +7 -7
- package/examples/basic/js/pages/app.css +33 -33
- package/examples/basic/js/pages/app.jsx +1 -1
- package/examples/basic/js/pages/index.jsx +18 -23
- package/examples/basic/js/pages/products/[id].jsx +5 -5
- package/examples/basic/js/zuby.config.mjs +2 -2
- package/examples/basic/ts/components/Card/index.module.css +24 -24
- package/examples/basic/ts/components/Card/index.tsx +11 -11
- package/examples/basic/ts/package.json +19 -19
- package/examples/basic/ts/pages/about.tsx +7 -7
- package/examples/basic/ts/pages/app.css +33 -33
- package/examples/basic/ts/pages/app.tsx +1 -1
- package/examples/basic/ts/pages/index.tsx +18 -23
- package/examples/basic/ts/pages/products/[id].tsx +5 -5
- package/examples/basic/ts/tsconfig.json +6 -6
- package/examples/basic/ts/zuby.config.ts +2 -2
- package/hooks/useFetch.d.ts +1 -1
- package/hooks/useFetch.js +11 -5
- package/hooks/useProps.d.ts +1 -1
- package/hooks/useProps.js +1 -1
- package/i18n/index.js +2 -4
- package/image/getNearestSize.d.ts +1 -1
- package/image/imageLoader.d.ts +1 -1
- package/logger/index.d.ts +1 -1
- package/logger/index.js +48 -0
- package/logger/types.d.ts +3 -0
- package/package.json +58 -57
- package/packageConfig.js +3 -1
- package/plugins/chunkNamingPlugin/index.d.ts +1 -1
- package/plugins/contextPlugin/index.d.ts +1 -1
- package/plugins/contextPlugin/index.js +5 -7
- package/plugins/dependenciesPlugin/index.d.ts +1 -1
- package/plugins/dependenciesPlugin/index.js +31 -3
- package/plugins/manifestPlugin/index.js +1 -1
- package/plugins/preloadPlugin/index.d.ts +1 -1
- package/plugins/preloadPlugin/index.js +2 -2
- package/plugins/prerenderPlugin/index.d.ts +1 -1
- package/plugins/prerenderPlugin/index.js +5 -12
- package/preload/index.js +61 -21
- package/server/index.js +146 -59
- package/server/types.d.ts +4 -4
- package/server/zubyDevRenderer.d.ts +4 -4
- package/server/zubyDevRenderer.js +11 -9
- package/server/zubyDevServer.d.ts +2 -2
- package/server/zubyDevServer.js +2 -5
- package/server/zubyRenderer.d.ts +5 -3
- package/server/zubyRenderer.js +44 -18
- package/server/zubyServer.d.ts +8 -7
- package/server/zubyServer.js +25 -30
- package/templates/index.d.ts +1 -1
- package/templates/index.js +8 -8
- package/templates/pathUtils.d.ts +2 -2
- package/templates/pathUtils.js +13 -5
- package/tsconfigs/default.json +18 -18
- package/types.d.ts +13 -6
- package/utils/brandingUtils.js +1 -1
- package/utils/errorUtils.d.ts +12 -0
- package/utils/errorUtils.js +25 -0
package/README.md
CHANGED
|
@@ -46,6 +46,15 @@ Zuby.js supports plugins to extend its functionality.
|
|
|
46
46
|
You can find official plugins in the `@zubyjs` namespace on npm.
|
|
47
47
|
See the complete [ZubyPlugin API](https://zuby.futrou.com/reference/zuby-plugin) to learn how to create your own plugins.
|
|
48
48
|
|
|
49
|
+
Official plugins:
|
|
50
|
+
### Official Plugins
|
|
51
|
+
|
|
52
|
+
- [**@zubyjs/share**](./packages/share) - Share your local development server with others using Cloudflare tunnels
|
|
53
|
+
- [**@zubyjs/sitemap**](./packages/sitemap) - Automatically generate sitemaps for your application
|
|
54
|
+
- [**@zubyjs/tailwind**](./packages/tailwind) - Tailwind CSS integration and optimization
|
|
55
|
+
- [**@zubyjs/purgecss**](./packages/purgecss) - CSS purging and optimization
|
|
56
|
+
- [**@zubyjs/image**](./packages/image) - Image optimization and responsive image generation
|
|
57
|
+
|
|
49
58
|
## Acknowledgements
|
|
50
59
|
|
|
51
60
|
Zuby.js is inspired by [Astro](https://astro.build/) and [Next.js](https://nextjs.org/)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function add(options: Record<string, any>): Promise<void>;
|
package/commands/add.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createLogger } from '../logger/index.js';
|
|
2
|
+
import { getZubyPackageConfig } from '../packageConfig.js';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { getErrorMessage } from '../utils/errorUtils.js';
|
|
5
|
+
/**
|
|
6
|
+
* Fetches available packages from NPM registry under @zubyjs scope
|
|
7
|
+
*/
|
|
8
|
+
async function fetchAvailablePackages() {
|
|
9
|
+
try {
|
|
10
|
+
const response = await fetch('https://registry.npmjs.org/-/v1/search?q=scope:zubyjs', {
|
|
11
|
+
signal: AbortSignal.timeout(5000),
|
|
12
|
+
});
|
|
13
|
+
if (!response.ok) {
|
|
14
|
+
throw new Error(`Failed to fetch packages from NPM registry: ${response.statusText}`);
|
|
15
|
+
}
|
|
16
|
+
const data = (await response.json());
|
|
17
|
+
if (!data.objects) {
|
|
18
|
+
throw new Error('Invalid response format from NPM registry');
|
|
19
|
+
}
|
|
20
|
+
const packages = {};
|
|
21
|
+
data.objects.forEach((item) => {
|
|
22
|
+
const { name, version } = item.package;
|
|
23
|
+
packages[name] = version;
|
|
24
|
+
});
|
|
25
|
+
return packages;
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
throw new Error(`Failed to fetch available packages: ${getErrorMessage(error)}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Gets the package manager command (npm, yarn, or pnpm)
|
|
33
|
+
*/
|
|
34
|
+
function getPackageManagerCommand() {
|
|
35
|
+
// Check which package manager is being used
|
|
36
|
+
const userAgent = process.env.npm_config_user_agent || '';
|
|
37
|
+
if (userAgent.includes('yarn')) {
|
|
38
|
+
return 'yarn add';
|
|
39
|
+
}
|
|
40
|
+
if (userAgent.includes('pnpm')) {
|
|
41
|
+
return 'pnpm add';
|
|
42
|
+
}
|
|
43
|
+
return 'npm install';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Installs a plugin package using the appropriate package manager
|
|
47
|
+
*/
|
|
48
|
+
async function installPlugin(packageName, version) {
|
|
49
|
+
const { execSync } = await import('child_process');
|
|
50
|
+
const packageManagerCmd = getPackageManagerCommand();
|
|
51
|
+
try {
|
|
52
|
+
const fullPackageName = `${packageName}@${version}`;
|
|
53
|
+
execSync(`${packageManagerCmd} ${fullPackageName}`, { stdio: 'inherit' });
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
throw new Error(`Failed to install plugin ${packageName}: ${getErrorMessage(error)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export default async function add(options) {
|
|
60
|
+
const logger = createLogger();
|
|
61
|
+
logger.clearScreen('info');
|
|
62
|
+
const zubyConfig = getZubyPackageConfig();
|
|
63
|
+
const zubyVersion = zubyConfig.version;
|
|
64
|
+
// Get plugin names from rest arguments
|
|
65
|
+
const pluginNames = options.args || [];
|
|
66
|
+
if (pluginNames.length === 0) {
|
|
67
|
+
logger.error('No plugin names provided. Usage: npx zuby add [plugin-name] [another-plugin]');
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
logger.info(`Fetching available @zubyjs packages...`);
|
|
71
|
+
try {
|
|
72
|
+
const availablePackages = await fetchAvailablePackages();
|
|
73
|
+
const pluginsToInstall = [];
|
|
74
|
+
// Validate each plugin
|
|
75
|
+
for (const pluginName of pluginNames) {
|
|
76
|
+
const fullPackageName = pluginName.startsWith('@zubyjs/') ? pluginName : `@zubyjs/${pluginName}`;
|
|
77
|
+
if (!(fullPackageName in availablePackages)) {
|
|
78
|
+
logger.error(`Plugin ${chalk.bold(fullPackageName)} not found in @zubyjs scope`);
|
|
79
|
+
logger.info(`Available plugins: ${Object.keys(availablePackages).join(', ')}`);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
const pluginVersion = availablePackages[fullPackageName];
|
|
83
|
+
// Check if plugin version matches Zuby version
|
|
84
|
+
if (pluginVersion !== zubyVersion) {
|
|
85
|
+
logger.warn(`Plugin ${chalk.bold(fullPackageName)} has version ${chalk.bold(pluginVersion)}, but you have Zuby version ${chalk.bold(zubyVersion)}`);
|
|
86
|
+
logger.info('Using the exact version match for compatibility');
|
|
87
|
+
}
|
|
88
|
+
pluginsToInstall.push({
|
|
89
|
+
name: fullPackageName,
|
|
90
|
+
version: zubyVersion,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
logger.info(`\nInstalling ${pluginsToInstall.length} plugin(s) with Zuby version ${chalk.bold(zubyVersion)}...\r\n`);
|
|
94
|
+
// Install all plugins
|
|
95
|
+
for (const plugin of pluginsToInstall) {
|
|
96
|
+
try {
|
|
97
|
+
await installPlugin(plugin.name, plugin.version);
|
|
98
|
+
logger.info(`${chalk.greenBright('✓')} Successfully installed ${chalk.bold(plugin.name)}`);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
logger.error(getErrorMessage(error));
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
logger.info(`\r\n${chalk.greenBright.bold('All plugins installed successfully! 🎉')}\r\n`);
|
|
106
|
+
logger.info('Update your zuby.config.ts or zuby.config.js to use the installed plugins.');
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
logger.error(getErrorMessage(error));
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
}
|
package/commands/build.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { BuildCommandOptions, ZubyInternalConfig } from '../types.js';
|
|
1
|
+
import { type BuildCommandOptions, type ZubyInternalConfig } from '../types.js';
|
|
2
2
|
export default function build(options: BuildCommandOptions): Promise<void>;
|
|
3
3
|
export declare function getEntryFile(zubyInternalConfig: ZubyInternalConfig): Promise<string>;
|
package/commands/build.js
CHANGED
|
@@ -5,7 +5,7 @@ import { getTitle } from '../utils/brandingUtils.js';
|
|
|
5
5
|
import { build as viteBuild } from 'vite';
|
|
6
6
|
import { dirname, join, resolve } from 'path';
|
|
7
7
|
import { normalizePath } from '../utils/pathUtils.js';
|
|
8
|
-
import { existsSync, rmSync, writeFileSync, copyFileSync, readFileSync
|
|
8
|
+
import { existsSync, rmSync, writeFileSync, copyFileSync, readFileSync } from 'fs';
|
|
9
9
|
import { TEMPLATES } from '../templates/types.js';
|
|
10
10
|
import { glob } from 'glob';
|
|
11
11
|
import { fileURLToPath } from 'url';
|
|
@@ -19,7 +19,7 @@ export default async function build(options) {
|
|
|
19
19
|
const zubyInternalConfig = await getZubyInternalConfig(options.configFile);
|
|
20
20
|
const { vite: viteConfig, customLogger: logger, outDir, cacheDir, plugins } = zubyInternalConfig;
|
|
21
21
|
let buildStep = 1;
|
|
22
|
-
const buildSteps = 2 + plugins.filter(plugin => plugin?.buildStep).length;
|
|
22
|
+
const buildSteps = 2 + plugins.filter((plugin) => plugin?.buildStep).length;
|
|
23
23
|
const nextBuildStep = (description) => {
|
|
24
24
|
logger?.info(`${chalk.bgYellow.bold.whiteBright(` Step ${buildStep++}/${buildSteps} `)} ${chalk.gray(description)}`);
|
|
25
25
|
};
|
|
@@ -110,10 +110,26 @@ export default async function build(options) {
|
|
|
110
110
|
const clientChunksManifestPath = resolve(outDir, CLIENT_CHUNKS_MANIFEST);
|
|
111
111
|
const serverChunksManifestPath = resolve(outDir, SERVER_CHUNKS_MANIFEST);
|
|
112
112
|
const clientChunksManifest = existsSync(clientChunksManifestPath)
|
|
113
|
-
?
|
|
113
|
+
? (() => {
|
|
114
|
+
try {
|
|
115
|
+
return JSON.parse(readFileSync(clientChunksManifestPath, 'utf-8'));
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
logger?.warn(`Failed to parse client chunks manifest: ${error instanceof Error ? error.message : String(error)}`);
|
|
119
|
+
return {};
|
|
120
|
+
}
|
|
121
|
+
})()
|
|
114
122
|
: {};
|
|
115
123
|
const serverChunksManifest = existsSync(serverChunksManifestPath)
|
|
116
|
-
?
|
|
124
|
+
? (() => {
|
|
125
|
+
try {
|
|
126
|
+
return JSON.parse(readFileSync(serverChunksManifestPath, 'utf-8'));
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
logger?.warn(`Failed to parse server chunks manifest: ${error instanceof Error ? error.message : String(error)}`);
|
|
130
|
+
return {};
|
|
131
|
+
}
|
|
132
|
+
})()
|
|
117
133
|
: {};
|
|
118
134
|
// Run build done hook
|
|
119
135
|
// to execute plugins that are part of the build process
|
|
@@ -122,7 +138,7 @@ export default async function build(options) {
|
|
|
122
138
|
translationFiles,
|
|
123
139
|
clientChunksManifest,
|
|
124
140
|
serverChunksManifest,
|
|
125
|
-
}, zubyPlugin => {
|
|
141
|
+
}, (zubyPlugin) => {
|
|
126
142
|
// Hide plugins that are not part of the build process
|
|
127
143
|
// from the CLI output to avoid confusion
|
|
128
144
|
if (!zubyPlugin.buildStep)
|
package/commands/dev.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ServerCommandOptions } from '../types.js';
|
|
1
|
+
import { type ServerCommandOptions } from '../types.js';
|
|
2
2
|
export default function dev(options: ServerCommandOptions): Promise<void>;
|
package/commands/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import preview from './preview.js';
|
|
|
7
7
|
import init from './init.js';
|
|
8
8
|
import info from './info.js';
|
|
9
9
|
import upgrade from './upgrade.js';
|
|
10
|
+
import add from './add.js';
|
|
10
11
|
const { name, description, version } = getZubyPackageConfig();
|
|
11
12
|
const program = new Command().name(name).description(description).version(version);
|
|
12
13
|
program
|
|
@@ -46,4 +47,8 @@ program
|
|
|
46
47
|
.description('Upgrades Zuby to the latest compatible version')
|
|
47
48
|
.option('-t, --tag <tag>', 'The tag to upgrade to (e.g. v1, v2, latest)')
|
|
48
49
|
.action(async (options) => upgrade(options));
|
|
50
|
+
program
|
|
51
|
+
.command('add [plugins...]')
|
|
52
|
+
.description('Adds one or more Zuby plugins to your project')
|
|
53
|
+
.action(async (plugins, options) => add({ ...options, args: plugins }));
|
|
49
54
|
program.parse(process.argv);
|
package/commands/info.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { BaseCommandOptions } from '../types.js';
|
|
1
|
+
import type { BaseCommandOptions } from '../types.js';
|
|
2
2
|
export default function info({ configFile }: BaseCommandOptions): Promise<void>;
|
package/commands/info.js
CHANGED
|
@@ -9,6 +9,6 @@ export default async function info({ configFile }) {
|
|
|
9
9
|
logger.info(`OS: ${os.type()} ${os.release()}`);
|
|
10
10
|
logger.info(`Output: ${output}`);
|
|
11
11
|
logger.info(`Output dir: ${outDir}`);
|
|
12
|
-
const pluginNames = plugins.map(plugin => plugin.name).join(', ');
|
|
12
|
+
const pluginNames = plugins.map((plugin) => plugin.name).join(', ');
|
|
13
13
|
logger.info(`Plugins: ${plugins.length ? pluginNames : 'none'}`);
|
|
14
14
|
}
|
package/commands/init.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { InitCommandOptions } from '../types.js';
|
|
2
|
-
export default function init({ projectPath, jsxProviderName, exampleName, useTypescript
|
|
1
|
+
import type { InitCommandOptions } from '../types.js';
|
|
2
|
+
export default function init({ projectPath, jsxProviderName, exampleName, useTypescript }: InitCommandOptions): Promise<void>;
|
|
3
3
|
export declare function initExample(example: Example, options: InitOptions): Promise<void>;
|
|
4
4
|
export declare function getExamples(): Example[];
|
|
5
5
|
export interface Example {
|
package/commands/init.js
CHANGED
|
@@ -11,16 +11,16 @@ import { getZubyPackageConfig } from '../packageConfig.js';
|
|
|
11
11
|
import { globSync } from 'glob';
|
|
12
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
13
|
const __dirname = dirname(__filename);
|
|
14
|
-
export default async function init({ projectPath, jsxProviderName, exampleName, useTypescript
|
|
14
|
+
export default async function init({ projectPath, jsxProviderName, exampleName, useTypescript }) {
|
|
15
15
|
const logger = createLogger();
|
|
16
16
|
logger.clearScreen('info');
|
|
17
17
|
logger?.info(`${getTitle(`Let's get started with Zuby`)}\r\n`);
|
|
18
18
|
logger.info('Initializing a new Zuby project');
|
|
19
19
|
const examples = getExamples();
|
|
20
20
|
const defaultProjectName = 'my-zuby-app';
|
|
21
|
-
const defaultExample = examples.find(example => example.name === 'basic');
|
|
21
|
+
const defaultExample = examples.find((example) => example.name === 'basic');
|
|
22
22
|
const jsxProviderNames = ['preact', 'react'];
|
|
23
|
-
const exampleNames = examples.map(example => example.name);
|
|
23
|
+
const exampleNames = examples.map((example) => example.name);
|
|
24
24
|
const validateProjectPath = (projectPath) => {
|
|
25
25
|
if (existsSync(projectPath)) {
|
|
26
26
|
return 'Project with this name already exists. Please choose a different one.';
|
|
@@ -86,7 +86,7 @@ export default async function init({ projectPath, jsxProviderName, exampleName,
|
|
|
86
86
|
else {
|
|
87
87
|
logger.info(`Example project: ${exampleName}`);
|
|
88
88
|
}
|
|
89
|
-
const selectedExample = examples.find(example => example.name === exampleName);
|
|
89
|
+
const selectedExample = examples.find((example) => example.name === exampleName);
|
|
90
90
|
if (!selectedExample) {
|
|
91
91
|
logger.error(`Example ${exampleName} was not found`);
|
|
92
92
|
process.exit(1);
|
|
@@ -145,7 +145,7 @@ options) {
|
|
|
145
145
|
export function getExamples() {
|
|
146
146
|
const examplesPath = normalizePath(join(__dirname, '..', 'examples'));
|
|
147
147
|
const exampleNames = readdirSync(examplesPath);
|
|
148
|
-
return exampleNames.map(exampleName => ({
|
|
148
|
+
return exampleNames.map((exampleName) => ({
|
|
149
149
|
name: exampleName,
|
|
150
150
|
path: normalizePath(join(examplesPath, exampleName)),
|
|
151
151
|
isJs: existsSync(normalizePath(join(examplesPath, exampleName, 'js'))),
|
package/commands/preview.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ServerCommandOptions } from '../types.js';
|
|
1
|
+
import { type ServerCommandOptions } from '../types.js';
|
|
2
2
|
export default function preview(options: ServerCommandOptions): Promise<void>;
|
package/commands/upgrade.d.ts
CHANGED
package/commands/upgrade.js
CHANGED
|
@@ -15,12 +15,25 @@ export default async function upgrade({ configFile, tag }) {
|
|
|
15
15
|
process.exit(1);
|
|
16
16
|
}
|
|
17
17
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
let tags;
|
|
19
|
+
try {
|
|
20
|
+
const res = await fetch('https://registry.npmjs.org/-/package/zuby/dist-tags', {
|
|
21
|
+
signal: AbortSignal.timeout(5000),
|
|
22
|
+
});
|
|
23
|
+
if (!res.ok) {
|
|
24
|
+
logger.error(`ERROR: Failed to fetch latest version from NPM.`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
tags = (await res.json());
|
|
28
|
+
if (!tags || typeof tags !== 'object' || !tags.latest) {
|
|
29
|
+
logger.error(`ERROR: Invalid response from NPM registry.`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
logger.error(`ERROR: Failed to check for latest version: ${error instanceof Error ? error.message : String(error)}`);
|
|
21
35
|
process.exit(1);
|
|
22
36
|
}
|
|
23
|
-
const tags = (await res.json());
|
|
24
37
|
const latestVersion = tags.latest;
|
|
25
38
|
const selectedVersion = tags[tag || `v${currentMajor}`] || latestVersion;
|
|
26
39
|
logger.info(getTitle(`Checking...`));
|
|
@@ -42,8 +55,9 @@ export default async function upgrade({ configFile, tag }) {
|
|
|
42
55
|
Object.keys({
|
|
43
56
|
...(packageJson.dependencies || {}),
|
|
44
57
|
...(packageJson.devDependencies || {}),
|
|
45
|
-
}).forEach(name => {
|
|
46
|
-
|
|
58
|
+
}).forEach((name) => {
|
|
59
|
+
// Match packages starting with 'zuby' or '@zubyjs/'
|
|
60
|
+
if (!name.match(/^(zuby|@zubyjs\/)(.+)?$/i))
|
|
47
61
|
return;
|
|
48
62
|
if (packageJson.dependencies?.[name]) {
|
|
49
63
|
packageJson.dependencies[name] = selectedVersion;
|
package/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PluginHook, ZubyConfig, ZubyHookParams, ZubyInternalConfig, ZubyPlugin } from './types.js';
|
|
1
|
+
import { type PluginHook, type ZubyConfig, type ZubyHookParams, type ZubyInternalConfig, type ZubyPlugin } from './types.js';
|
|
2
2
|
import type { PluginOption as VitePluginOption, Plugin as VitePlugin } from 'vite';
|
|
3
3
|
/**
|
|
4
4
|
* Returns the path to the ZubyConfig file.
|
package/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PLUGIN_HOOKS
|
|
1
|
+
import { PLUGIN_HOOKS } from './types.js';
|
|
2
2
|
import { BUILD_CHUNKS_MANIFEST, ZUBY_CONFIG_FILE } from './constants.js';
|
|
3
3
|
import { existsSync } from 'fs';
|
|
4
4
|
import { randomBytes } from 'crypto';
|
|
@@ -24,11 +24,7 @@ let zubyInternalConfig;
|
|
|
24
24
|
*/
|
|
25
25
|
export const getDefaultConfigPath = () => {
|
|
26
26
|
// Find the config file with various extensions
|
|
27
|
-
return [
|
|
28
|
-
ZUBY_CONFIG_FILE,
|
|
29
|
-
ZUBY_CONFIG_FILE.replace(/\.mjs$/, '.js'),
|
|
30
|
-
ZUBY_CONFIG_FILE.replace(/\.mjs$/, '.ts'),
|
|
31
|
-
].find(file => existsSync(file));
|
|
27
|
+
return [ZUBY_CONFIG_FILE, ZUBY_CONFIG_FILE.replace(/\.mjs$/, '.js'), ZUBY_CONFIG_FILE.replace(/\.mjs$/, '.ts')].find((file) => existsSync(file));
|
|
32
28
|
};
|
|
33
29
|
/**
|
|
34
30
|
* This function loads the config file and returns the config object.
|
|
@@ -162,11 +158,7 @@ export const mergeDefaultConfig = async (config) => {
|
|
|
162
158
|
config.cacheDir = config.cacheDir ?? '.zuby-cache';
|
|
163
159
|
config.output = config.output ?? 'static';
|
|
164
160
|
config.prerenderPaths = config.prerenderPaths ?? [];
|
|
165
|
-
config.plugins = await normalizePlugins([
|
|
166
|
-
...getBuiltInPlugins(),
|
|
167
|
-
...(config.jsx?.getPlugins() ?? []),
|
|
168
|
-
...(config.plugins ?? []),
|
|
169
|
-
]);
|
|
161
|
+
config.plugins = await normalizePlugins([...getBuiltInPlugins(), ...(config.jsx?.getPlugins() ?? []), ...(config.plugins ?? [])]);
|
|
170
162
|
// Default server config
|
|
171
163
|
config.server = config.server ?? {};
|
|
172
164
|
config.server.host = config.server.host ?? '127.0.0.1';
|
|
@@ -180,8 +172,7 @@ export const mergeDefaultConfig = async (config) => {
|
|
|
180
172
|
// Image config
|
|
181
173
|
config.image = config.image ?? {};
|
|
182
174
|
config.image.sizes = config.image.sizes ?? [160, 320, 640, 768, 1024, 1280, 1536, 1920, 2048];
|
|
183
|
-
config.image.loader =
|
|
184
|
-
config.image.loader ?? normalizePath(resolve(__dirname, 'image', 'imageLoader.js'));
|
|
175
|
+
config.image.loader = config.image.loader ?? normalizePath(resolve(__dirname, 'image', 'imageLoader.js'));
|
|
185
176
|
config.image.defaultFormat = config.image.defaultFormat ?? 'webp';
|
|
186
177
|
config.image.defaultQuality = config.image.defaultQuality ?? 80;
|
|
187
178
|
// Build ID generator
|
|
@@ -243,15 +234,7 @@ export const mergeDefaultConfig = async (config) => {
|
|
|
243
234
|
* before removing any of them.
|
|
244
235
|
*/
|
|
245
236
|
export const getBuiltInPlugins = () => {
|
|
246
|
-
return [
|
|
247
|
-
injectPlugin(),
|
|
248
|
-
contextPlugin(),
|
|
249
|
-
chunkNamingPlugin(),
|
|
250
|
-
manifestPlugin(),
|
|
251
|
-
prerenderPlugin(),
|
|
252
|
-
standaloneBuildPlugin(),
|
|
253
|
-
preloadPlugin(),
|
|
254
|
-
];
|
|
237
|
+
return [injectPlugin(), contextPlugin(), chunkNamingPlugin(), manifestPlugin(), prerenderPlugin(), standaloneBuildPlugin(), preloadPlugin()];
|
|
255
238
|
};
|
|
256
239
|
/**
|
|
257
240
|
* Executes the Zuby plugins for the given hook.
|
|
@@ -303,9 +286,9 @@ export const normalizePlugins = async (plugins) => {
|
|
|
303
286
|
const resolvePlugins = await Promise.resolve(plugins);
|
|
304
287
|
return resolvePlugins
|
|
305
288
|
// Flatten the array and normalize inner arrays
|
|
306
|
-
.flatMap(plugin => (Array.isArray(plugin) ? normalizePlugins(plugin) : [plugin]))
|
|
289
|
+
.flatMap((plugin) => (Array.isArray(plugin) ? normalizePlugins(plugin) : [plugin]))
|
|
307
290
|
// Remove false, undefined, null values
|
|
308
|
-
.filter(plugin => !!plugin);
|
|
291
|
+
.filter((plugin) => !!plugin);
|
|
309
292
|
};
|
|
310
293
|
/**
|
|
311
294
|
* Returns random base32 like build ID
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LazyTemplate } from '../templates/types.js';
|
|
2
|
-
import { ImageFormat, ImageLoader, RenderToStream, RenderToString } from '../types.js';
|
|
1
|
+
import type { LazyTemplate } from '../templates/types.js';
|
|
2
|
+
import type { ImageFormat, ImageLoader, RenderToStream, RenderToString } from '../types.js';
|
|
3
3
|
export interface GlobalContext {
|
|
4
4
|
/**
|
|
5
5
|
* The array with templates.
|
package/contexts/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './globalContext.js';
|
|
2
2
|
export * from './pageContext.js';
|
|
3
|
-
export { PageContext as HandlerContext } from './pageContext.js';
|
|
4
|
-
export { PageContext as ZubyPageContext } from './pageContext.js';
|
|
5
|
-
export { PageContext as ZubyHandlerContext } from './pageContext.js';
|
|
6
|
-
export { GlobalContext as ZubyGlobalContext } from './globalContext.js';
|
|
3
|
+
export type { PageContext as HandlerContext } from './pageContext.js';
|
|
4
|
+
export type { PageContext as ZubyPageContext } from './pageContext.js';
|
|
5
|
+
export type { PageContext as ZubyHandlerContext } from './pageContext.js';
|
|
6
|
+
export type { GlobalContext as ZubyGlobalContext } from './globalContext.js';
|
package/contexts/index.js
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
1
|
export * from './globalContext.js';
|
|
2
2
|
export * from './pageContext.js';
|
|
3
|
-
export { PageContext as HandlerContext } from './pageContext.js';
|
|
4
|
-
export { PageContext as ZubyPageContext } from './pageContext.js';
|
|
5
|
-
export { PageContext as ZubyHandlerContext } from './pageContext.js';
|
package/contexts/pageContext.js
CHANGED
|
@@ -233,7 +233,7 @@ export class PageContext {
|
|
|
233
233
|
* @example /products/1
|
|
234
234
|
*/
|
|
235
235
|
get isInitialPath() {
|
|
236
|
-
return
|
|
236
|
+
return this._initialPath.replace(/(.+)\/+$/, '$1') === this.url.pathname.replace(/(.+)\/+$/, '$1');
|
|
237
237
|
}
|
|
238
238
|
/**
|
|
239
239
|
* Returns array of all locales
|
|
@@ -262,7 +262,7 @@ export class PageContext {
|
|
|
262
262
|
*/
|
|
263
263
|
get locale() {
|
|
264
264
|
const currentPath = `${this.url.pathname}/`;
|
|
265
|
-
return this.locales.find(locale => currentPath.startsWith(`/${locale}/`)) || this.defaultLocale;
|
|
265
|
+
return this.locales.find((locale) => currentPath.startsWith(`/${locale}/`)) || this.defaultLocale;
|
|
266
266
|
}
|
|
267
267
|
/**
|
|
268
268
|
* Returns path prefixed for given locale.
|
|
@@ -283,7 +283,7 @@ export class PageContext {
|
|
|
283
283
|
* @example getPathLocale('/de/products/1') => 'de'
|
|
284
284
|
*/
|
|
285
285
|
getPathLocale(path) {
|
|
286
|
-
return this.locales.find(locale => path.startsWith(`/${locale}`)) || this.defaultLocale;
|
|
286
|
+
return this.locales.find((locale) => path.startsWith(`/${locale}`)) || this.defaultLocale;
|
|
287
287
|
}
|
|
288
288
|
/**
|
|
289
289
|
* Localizes the given text for the current locale
|
|
@@ -359,7 +359,7 @@ export class PageContext {
|
|
|
359
359
|
* @private
|
|
360
360
|
*/
|
|
361
361
|
async getHeadElements() {
|
|
362
|
-
return Promise.all(this._headElements.map(element => this.getElement(element)));
|
|
362
|
+
return Promise.all(this._headElements.map((element) => this.getElement(element)));
|
|
363
363
|
}
|
|
364
364
|
/**
|
|
365
365
|
* Returns array of all elements as string
|
|
@@ -367,7 +367,7 @@ export class PageContext {
|
|
|
367
367
|
* @private
|
|
368
368
|
*/
|
|
369
369
|
async getBodyElements() {
|
|
370
|
-
return Promise.all(this._bodyElements.map(element => this.getElement(element)));
|
|
370
|
+
return Promise.all(this._bodyElements.map((element) => this.getElement(element)));
|
|
371
371
|
}
|
|
372
372
|
/**
|
|
373
373
|
* Renders the given HTML element
|
package/defineConfig.d.ts
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
.link-card {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
list-style: none;
|
|
3
|
+
display: flex;
|
|
4
|
+
padding: 1px;
|
|
5
|
+
background-color: #23262d;
|
|
6
|
+
background-image: none;
|
|
7
|
+
background-size: 400%;
|
|
8
|
+
border-radius: 7px;
|
|
9
|
+
background-position: 100%;
|
|
10
|
+
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
|
11
|
+
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
|
|
12
12
|
}
|
|
13
13
|
.link-card > a {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
width: 100%;
|
|
15
|
+
text-decoration: none;
|
|
16
|
+
line-height: 1.4;
|
|
17
|
+
padding: calc(1.5rem - 1px);
|
|
18
|
+
border-radius: 8px;
|
|
19
|
+
color: white;
|
|
20
|
+
background-color: #23262d;
|
|
21
|
+
opacity: 0.8;
|
|
22
22
|
}
|
|
23
23
|
h2 {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
margin: 0;
|
|
25
|
+
font-size: 1.25rem;
|
|
26
|
+
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
|
27
27
|
}
|
|
28
28
|
p {
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
margin-top: 0.5rem;
|
|
30
|
+
margin-bottom: 0;
|
|
31
31
|
}
|
|
32
32
|
.link-card:is(:hover, :focus-within) {
|
|
33
|
-
|
|
33
|
+
background-position: 0;
|
|
34
34
|
}
|
|
35
35
|
.link-card:is(:hover, :focus-within) h2 {
|
|
36
|
-
|
|
36
|
+
color: #ffcc00;
|
|
37
37
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import styles from './index.module.css';
|
|
2
2
|
|
|
3
3
|
export default function Card({ href, title, body }) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
return (
|
|
5
|
+
<li className={styles.linkCard}>
|
|
6
|
+
<a href={href}>
|
|
7
|
+
<h2>
|
|
8
|
+
{title}
|
|
9
|
+
<span>→</span>
|
|
10
|
+
</h2>
|
|
11
|
+
<p>{body}</p>
|
|
12
|
+
</a>
|
|
13
|
+
</li>
|
|
14
|
+
);
|
|
15
15
|
}
|