@evertondgn/solid-tooling 0.2.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/README.md +406 -20
- package/dist/has-match-BITlj0EE.mjs +9 -0
- package/dist/knip.d.mts +12 -0
- package/dist/knip.mjs +92 -0
- package/dist/lint-UTfyg7AR.mjs +983 -0
- package/dist/lint.mjs +1 -983
- package/dist/playwright-teardown.d.mts +1 -0
- package/dist/playwright-teardown.mjs +23 -0
- package/dist/playwright.d.mts +18 -0
- package/dist/playwright.mjs +158 -0
- package/dist/stylelint.d.mts +8 -0
- package/dist/stylelint.mjs +180 -0
- package/dist/vite.d.mts +40 -0
- package/dist/vite.mjs +341 -0
- package/dist/vitest-setup/browser.d.mts +1 -0
- package/dist/vitest-setup/browser.mjs +5 -0
- package/dist/vitest.d.mts +7 -0
- package/dist/vitest.mjs +129 -0
- package/package.json +50 -7
- package/tsconfig.app.json +21 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function checkServerLog(): Promise<void>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { env } from "node:process";
|
|
3
|
+
import { stripVTControlCharacters } from "node:util";
|
|
4
|
+
// src/playwright/teardown.ts
|
|
5
|
+
const PRIVATE_MARKER = /PRIVATE_[A-Z0-9_]+/u;
|
|
6
|
+
async function checkLog({ file, baseUrl }) {
|
|
7
|
+
if (!file || !baseUrl) throw new Error("Server log file is not configured");
|
|
8
|
+
const log = stripVTControlCharacters(await readFile(file, "utf8"));
|
|
9
|
+
const { host } = new URL(baseUrl);
|
|
10
|
+
if (!log.includes(host)) throw new Error(`Server log does not show the preview startup: ${file}`);
|
|
11
|
+
if (PRIVATE_MARKER.test(log)) throw new Error(`Server log contains a private marker: ${file}`);
|
|
12
|
+
}
|
|
13
|
+
async function checkServerLog() {
|
|
14
|
+
await checkLog({
|
|
15
|
+
file: env.SERVER_LOG_FILE,
|
|
16
|
+
baseUrl: env.BASE_URL_TEST
|
|
17
|
+
});
|
|
18
|
+
if (env.TEST_PUBLICATION_LOAD === "true") await checkLog({
|
|
19
|
+
file: env.SERVER_LOG_SECONDARY,
|
|
20
|
+
baseUrl: env.PUBLICATION_SECONDARY_URL
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export { checkServerLog as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PlaywrightTestConfig } from "@playwright/test";
|
|
2
|
+
type FixtureServer = {
|
|
3
|
+
command: string;
|
|
4
|
+
url: string;
|
|
5
|
+
};
|
|
6
|
+
type SerialSuites = {
|
|
7
|
+
serverLogs?: string;
|
|
8
|
+
markdown?: string;
|
|
9
|
+
publicationLoad?: string;
|
|
10
|
+
};
|
|
11
|
+
type PlaywrightOptions = {
|
|
12
|
+
root: string;
|
|
13
|
+
testDir?: string;
|
|
14
|
+
fixtureServers?: FixtureServer[];
|
|
15
|
+
suites?: SerialSuites;
|
|
16
|
+
};
|
|
17
|
+
export declare function definePlaywrightConfig({ root, testDir, fixtureServers, suites }: PlaywrightOptions): PlaywrightTestConfig;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { env, loadEnvFile } from "node:process";
|
|
4
|
+
import { loadEnv } from "vite-plus";
|
|
5
|
+
import { defineConfig as defineConfig$1, devices } from "@playwright/test";
|
|
6
|
+
// src/playwright/index.ts
|
|
7
|
+
const STARTUP_TIMEOUT = 12e4;
|
|
8
|
+
const SECONDARY_PORT_OFFSET = 2;
|
|
9
|
+
const MAX_PORT = 65535;
|
|
10
|
+
const CI_WORKERS = 2;
|
|
11
|
+
const SECONDARY_LOG = "test-results/server-publication-secondary.log";
|
|
12
|
+
const PREBUILT_GUARD = "if [ -e .vercel/output/static/.vite ]; then echo 'TEST_PREBUILT found an e2e build; run vp run build first' >&2; exit 1; fi && ";
|
|
13
|
+
function readRunMode(suites) {
|
|
14
|
+
const mode = {
|
|
15
|
+
isProduction: env.TEST_PRODUCTION_ROUTES === "true",
|
|
16
|
+
isPublicationLoad: env.TEST_PUBLICATION_LOAD === "true",
|
|
17
|
+
shouldBuild: env.TEST_PREBUILT !== "true"
|
|
18
|
+
};
|
|
19
|
+
if (mode.isPublicationLoad && mode.isProduction) throw new Error("TEST_PUBLICATION_LOAD requires fixture routes");
|
|
20
|
+
if (mode.isPublicationLoad && !suites.publicationLoad) throw new Error("TEST_PUBLICATION_LOAD requires a publicationLoad suite");
|
|
21
|
+
if (!mode.shouldBuild && !mode.isProduction) throw new Error("TEST_PREBUILT requires production routes");
|
|
22
|
+
return mode;
|
|
23
|
+
}
|
|
24
|
+
function readBaseUrl(mode) {
|
|
25
|
+
if (!env.BASE_URL_TEST) throw new Error(".env.test must define BASE_URL_TEST");
|
|
26
|
+
const baseUrl = new URL(env.BASE_URL_TEST);
|
|
27
|
+
if (!baseUrl.port) throw new Error("BASE_URL_TEST must include an explicit port");
|
|
28
|
+
if (mode.isPublicationLoad && Number(baseUrl.port) + SECONDARY_PORT_OFFSET > MAX_PORT) throw new Error("BASE_URL_TEST leaves no port for the secondary server");
|
|
29
|
+
return env.BASE_URL_TEST;
|
|
30
|
+
}
|
|
31
|
+
function readWorkers(mode) {
|
|
32
|
+
if (mode.isPublicationLoad) return 1;
|
|
33
|
+
return env.CI ? CI_WORKERS : void 0;
|
|
34
|
+
}
|
|
35
|
+
function secondaryUrl(baseUrl) {
|
|
36
|
+
const url = new URL(baseUrl);
|
|
37
|
+
url.port = String(Number(url.port) + SECONDARY_PORT_OFFSET);
|
|
38
|
+
return url;
|
|
39
|
+
}
|
|
40
|
+
function buildProjects({ mode, suites }) {
|
|
41
|
+
if (mode.isPublicationLoad) return [{
|
|
42
|
+
name: "publication-load",
|
|
43
|
+
testMatch: suites.publicationLoad
|
|
44
|
+
}];
|
|
45
|
+
if (mode.isProduction) return [{ name: "chromium" }];
|
|
46
|
+
const teardown = suites.serverLogs ? { teardown: "server-logs" } : {};
|
|
47
|
+
const projects = [{
|
|
48
|
+
name: "chromium",
|
|
49
|
+
testIgnore: ["**/*.production.e2e.test.ts", ...[
|
|
50
|
+
suites.serverLogs,
|
|
51
|
+
suites.publicationLoad,
|
|
52
|
+
suites.markdown
|
|
53
|
+
].filter((suite) => suite !== void 0)],
|
|
54
|
+
...teardown
|
|
55
|
+
}];
|
|
56
|
+
if (suites.markdown) projects.push({
|
|
57
|
+
name: "markdown",
|
|
58
|
+
testMatch: suites.markdown,
|
|
59
|
+
fullyParallel: false,
|
|
60
|
+
workers: 1,
|
|
61
|
+
...teardown
|
|
62
|
+
});
|
|
63
|
+
if (suites.serverLogs) projects.push({
|
|
64
|
+
name: "server-logs",
|
|
65
|
+
testMatch: suites.serverLogs,
|
|
66
|
+
fullyParallel: false
|
|
67
|
+
});
|
|
68
|
+
return projects;
|
|
69
|
+
}
|
|
70
|
+
function buildServers({ root, mode, fixtureServers, baseUrl, serverLog }) {
|
|
71
|
+
const buildMode = mode.isProduction ? "production" : "e2e";
|
|
72
|
+
const build = mode.shouldBuild ? `vp run build --mode ${buildMode} && ` : PREBUILT_GUARD;
|
|
73
|
+
const shared = {
|
|
74
|
+
cwd: root,
|
|
75
|
+
reuseExistingServer: false
|
|
76
|
+
};
|
|
77
|
+
const server = {
|
|
78
|
+
...shared,
|
|
79
|
+
timeout: STARTUP_TIMEOUT
|
|
80
|
+
};
|
|
81
|
+
const fixtures = mode.isProduction ? [] : fixtureServers.map((fixture) => ({
|
|
82
|
+
...fixture,
|
|
83
|
+
...shared
|
|
84
|
+
}));
|
|
85
|
+
const { hostname, port } = new URL(baseUrl);
|
|
86
|
+
const secondary = secondaryUrl(baseUrl);
|
|
87
|
+
return [
|
|
88
|
+
...fixtures,
|
|
89
|
+
{
|
|
90
|
+
...server,
|
|
91
|
+
command: `${build}mkdir -p test-results && vp run start --strictPort > ${serverLog} 2>&1`,
|
|
92
|
+
env: {
|
|
93
|
+
HOST: hostname,
|
|
94
|
+
PORT: port,
|
|
95
|
+
NODE_ENV: "production"
|
|
96
|
+
},
|
|
97
|
+
url: baseUrl
|
|
98
|
+
},
|
|
99
|
+
...mode.isPublicationLoad ? [{
|
|
100
|
+
...server,
|
|
101
|
+
command: `vp run start --strictPort > ${SECONDARY_LOG} 2>&1`,
|
|
102
|
+
env: {
|
|
103
|
+
HOST: hostname,
|
|
104
|
+
PORT: secondary.port,
|
|
105
|
+
NODE_ENV: "production"
|
|
106
|
+
},
|
|
107
|
+
url: secondary.href
|
|
108
|
+
}] : []
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
function definePlaywrightConfig({ root, testDir = "src/tests/pages", fixtureServers = [], suites = {} }) {
|
|
112
|
+
loadEnvFile(path.join(root, ".env.test"));
|
|
113
|
+
const mode = readRunMode(suites);
|
|
114
|
+
const buildMode = mode.isProduction ? "production" : "e2e";
|
|
115
|
+
Object.assign(env, loadEnv(buildMode, root, "VITE_"));
|
|
116
|
+
const baseUrl = readBaseUrl(mode);
|
|
117
|
+
const serverLog = `test-results/server-${buildMode}.log`;
|
|
118
|
+
env.SERVER_LOG_FILE = path.join(root, serverLog);
|
|
119
|
+
if (mode.isPublicationLoad) {
|
|
120
|
+
env.PUBLICATION_SECONDARY_URL = secondaryUrl(baseUrl).href;
|
|
121
|
+
env.SERVER_LOG_SECONDARY = path.join(root, SECONDARY_LOG);
|
|
122
|
+
}
|
|
123
|
+
const reportFolder = mode.isProduction ? "production" : "e2e";
|
|
124
|
+
return defineConfig$1({
|
|
125
|
+
testDir: path.join(root, testDir),
|
|
126
|
+
testMatch: mode.isProduction ? "**/*.production.e2e.test.ts" : "**/*.e2e.test.ts",
|
|
127
|
+
outputDir: path.join(root, mode.isProduction ? "test-results/e2e-production" : "test-results/e2e"),
|
|
128
|
+
globalTeardown: fileURLToPath(new URL("playwright-teardown.mjs", import.meta.url)),
|
|
129
|
+
fullyParallel: !mode.isPublicationLoad,
|
|
130
|
+
forbidOnly: true,
|
|
131
|
+
workers: readWorkers(mode),
|
|
132
|
+
reporter: [["list"], ["html", {
|
|
133
|
+
outputFolder: path.join(root, "playwright-report", reportFolder),
|
|
134
|
+
open: "never",
|
|
135
|
+
onlyFailures: Boolean(env.CI)
|
|
136
|
+
}]],
|
|
137
|
+
use: {
|
|
138
|
+
...devices["Desktop Chrome"],
|
|
139
|
+
channel: env.CI ? "chrome" : void 0,
|
|
140
|
+
baseURL: baseUrl,
|
|
141
|
+
locale: "en-US",
|
|
142
|
+
screenshot: "only-on-failure",
|
|
143
|
+
trace: "retain-on-failure"
|
|
144
|
+
},
|
|
145
|
+
projects: buildProjects({
|
|
146
|
+
mode,
|
|
147
|
+
suites
|
|
148
|
+
}),
|
|
149
|
+
webServer: buildServers({
|
|
150
|
+
root,
|
|
151
|
+
mode,
|
|
152
|
+
fixtureServers,
|
|
153
|
+
baseUrl,
|
|
154
|
+
serverLog
|
|
155
|
+
})
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
export { definePlaywrightConfig };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Config } from "stylelint";
|
|
2
|
+
type CssCheck = {
|
|
3
|
+
report: string;
|
|
4
|
+
hasErrors: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare function defineStylelintConfig(appRoot: string): Promise<Config>;
|
|
7
|
+
export declare function checkCss(appRoot: string): Promise<CssCheck>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { cssFilenameError } from "./css-filename.mjs";
|
|
2
|
+
import { t as hasMatch } from "./has-match-BITlj0EE.mjs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { readdir } from "node:fs/promises";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import stylelint from "stylelint";
|
|
7
|
+
// src/stylelint/index.ts
|
|
8
|
+
const VAR = String.raw`var\(\s*--[a-z0-9-]+\s*\)`;
|
|
9
|
+
const TOKEN = String.raw`/^${VAR}(?:\s*[,/]\s*${VAR}|\s+${VAR})*$/`;
|
|
10
|
+
const LINE_HEIGHT = String.raw`(?:\d*\.?\d+(?:%|[a-z]+)?|normal)`;
|
|
11
|
+
const FONT_TOKEN = String.raw`/^${VAR}(?:\s+${VAR})*(?:\s*\/\s*(?:${LINE_HEIGHT}|${VAR})(?:\s+${VAR})*)?$/`;
|
|
12
|
+
const TOKEN_KEYWORDS = "/^(?:transparent|currentcolor|inherit|initial|unset|revert|revert-layer|none|auto)$/i";
|
|
13
|
+
const TOKEN_FAMILIES = [
|
|
14
|
+
"color",
|
|
15
|
+
"gradient",
|
|
16
|
+
"radius",
|
|
17
|
+
"shadow",
|
|
18
|
+
"ring",
|
|
19
|
+
"font-size",
|
|
20
|
+
"font-weight",
|
|
21
|
+
"z-index"
|
|
22
|
+
];
|
|
23
|
+
const REFERENCE_FILES = ["src/theme/tokens/**/*.css", "src/theme/class/animation.css"];
|
|
24
|
+
const SYSTEM_COLORS = `
|
|
25
|
+
AccentColor AccentColorText ActiveText ButtonBorder ButtonFace ButtonText
|
|
26
|
+
Canvas CanvasText Field FieldText GrayText Highlight HighlightText LinkText
|
|
27
|
+
Mark MarkText SelectedItem SelectedItemText VisitedText
|
|
28
|
+
ActiveBorder ActiveCaption AppWorkspace Background ButtonHighlight
|
|
29
|
+
ButtonShadow CaptionText InactiveBorder InactiveCaption InactiveCaptionText
|
|
30
|
+
InfoBackground InfoText Menu MenuText Scrollbar ThreeDDarkShadow ThreeDFace
|
|
31
|
+
ThreeDHighlight ThreeDLightShadow ThreeDShadow Window WindowFrame WindowText
|
|
32
|
+
-webkit-activelink -webkit-focus-ring-color -webkit-link -webkit-text
|
|
33
|
+
`.trim().split(/\s+/u);
|
|
34
|
+
const SYSTEM_COLOR = String.raw`/(?<![\w#./-])(?:${SYSTEM_COLORS.join("|")})(?![\w.-])/i`;
|
|
35
|
+
const NAME_PROPERTIES = String.raw`animation(?:-name)?|transition(?:-property)?|will-change|grid(?:-[a-z]+)*|container(?:-name)?|counter-(?:increment|reset|set)|view-transition-(?:class|name)|font-family|content|quotes|list-style(?:-type)?|page`;
|
|
36
|
+
const CSS_FILES = "src/**/*.css";
|
|
37
|
+
function property(names) {
|
|
38
|
+
return String.raw`/^(?!--)(?:-[a-z]+-)?(?:${names})$/i`;
|
|
39
|
+
}
|
|
40
|
+
const TOKEN_PROPERTIES = [
|
|
41
|
+
[property("(?:[a-z]+-)*color|fill|stroke"), ["/^--color-/"]],
|
|
42
|
+
[property("(?:[a-z]+-)*radius"), ["/^--radius-/"]],
|
|
43
|
+
[property("background"), ["/^--(?:color|gradient)-/"]],
|
|
44
|
+
[property("background-image"), ["/^--gradient-/"]],
|
|
45
|
+
[property("box-shadow"), ["/^--(?:shadow|ring)-/"]],
|
|
46
|
+
[property("text-shadow"), []],
|
|
47
|
+
[
|
|
48
|
+
property("font"),
|
|
49
|
+
["/^--font-/"],
|
|
50
|
+
FONT_TOKEN
|
|
51
|
+
],
|
|
52
|
+
[property("font-size"), ["/^--font-size-/"]],
|
|
53
|
+
[property("font-weight"), ["/^--font-weight-/"]],
|
|
54
|
+
[property("z-index"), ["/^--z-index-/"]],
|
|
55
|
+
...TOKEN_FAMILIES.map((family) => [`/^--${family}-/`, [`/^--${family}-/`]]),
|
|
56
|
+
[
|
|
57
|
+
"/^--font-(?!size-|weight-)/",
|
|
58
|
+
["/^--font-/"],
|
|
59
|
+
FONT_TOKEN
|
|
60
|
+
]
|
|
61
|
+
];
|
|
62
|
+
async function referenceFiles(root) {
|
|
63
|
+
return (await Promise.all(REFERENCE_FILES.map(async (pattern) => await hasMatch({
|
|
64
|
+
root,
|
|
65
|
+
pattern
|
|
66
|
+
}) ? [path.join(root, pattern)] : []))).flat();
|
|
67
|
+
}
|
|
68
|
+
async function filenameDiagnostics(root) {
|
|
69
|
+
return (await readdir(path.join(root, "src"), {
|
|
70
|
+
recursive: true,
|
|
71
|
+
withFileTypes: true
|
|
72
|
+
})).flatMap((entry) => {
|
|
73
|
+
if (!entry.isFile()) return [];
|
|
74
|
+
const absolute = path.join(entry.parentPath, entry.name);
|
|
75
|
+
const file = path.relative(root, absolute).split(path.sep).join("/");
|
|
76
|
+
if (!file.endsWith(".css")) return [];
|
|
77
|
+
const message = cssFilenameError(file);
|
|
78
|
+
return message ? [{
|
|
79
|
+
file,
|
|
80
|
+
message
|
|
81
|
+
}] : [];
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async function defineStylelintConfig(appRoot) {
|
|
85
|
+
const root = path.resolve(appRoot);
|
|
86
|
+
return {
|
|
87
|
+
referenceFiles: await referenceFiles(root),
|
|
88
|
+
reportDescriptionlessDisables: true,
|
|
89
|
+
plugins: [fileURLToPath(import.meta.resolve("stylelint-use-nesting"))],
|
|
90
|
+
rules: {
|
|
91
|
+
"property-no-unknown": true,
|
|
92
|
+
"declaration-property-value-no-unknown": true,
|
|
93
|
+
"value-no-invalid": true,
|
|
94
|
+
"unit-no-unknown": true,
|
|
95
|
+
"color-no-invalid-hex": true,
|
|
96
|
+
"color-no-hex": true,
|
|
97
|
+
"color-named": "never",
|
|
98
|
+
"declaration-block-no-duplicate-properties": [true, { ignore: ["consecutive-duplicates-with-different-syntaxes"] }],
|
|
99
|
+
"declaration-block-no-shorthand-property-overrides": true,
|
|
100
|
+
"selector-pseudo-class-no-unknown": true,
|
|
101
|
+
"selector-pseudo-element-no-unknown": true,
|
|
102
|
+
"selector-type-no-unknown": true,
|
|
103
|
+
"at-rule-no-unknown": true,
|
|
104
|
+
"no-unknown-animations": true,
|
|
105
|
+
"no-unknown-custom-properties": true,
|
|
106
|
+
"custom-property-no-missing-var-function": true,
|
|
107
|
+
"custom-property-pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$",
|
|
108
|
+
"selector-no-invalid": true,
|
|
109
|
+
"selector-no-deprecated": true,
|
|
110
|
+
"selector-no-unmatchable": true,
|
|
111
|
+
"at-charset-rule-no-invalid": true,
|
|
112
|
+
"media-query-no-invalid": true,
|
|
113
|
+
"media-feature-name-no-unknown": true,
|
|
114
|
+
"media-feature-name-value-no-unknown": true,
|
|
115
|
+
"function-calc-no-unspaced-operator": true,
|
|
116
|
+
"no-invalid-position-at-import-rule": true,
|
|
117
|
+
"no-duplicate-selectors": true,
|
|
118
|
+
"keyframe-block-no-duplicate-selectors": true,
|
|
119
|
+
"function-disallowed-list": [
|
|
120
|
+
"rgb",
|
|
121
|
+
"rgba",
|
|
122
|
+
"hsl",
|
|
123
|
+
"hsla",
|
|
124
|
+
"hwb",
|
|
125
|
+
"lab",
|
|
126
|
+
"lch",
|
|
127
|
+
"oklab",
|
|
128
|
+
"oklch",
|
|
129
|
+
"color",
|
|
130
|
+
"color-mix",
|
|
131
|
+
"light-dark",
|
|
132
|
+
"contrast-color",
|
|
133
|
+
"device-cmyk"
|
|
134
|
+
],
|
|
135
|
+
"value-type-custom-property-required-list": [["color"], { ignoreValues: [TOKEN_KEYWORDS] }],
|
|
136
|
+
"declaration-property-value-allowed-list": [Object.fromEntries(TOKEN_PROPERTIES.map(([name, , value = TOKEN]) => [name, [value, TOKEN_KEYWORDS]])), { message: "Use only var() tokens in this property; an exception needs a stylelint-disable comment with the reason." }],
|
|
137
|
+
"declaration-property-custom-property-allowed-list": [Object.fromEntries(TOKEN_PROPERTIES.map(([name, families]) => [name, families])), { message: "The property \"%s\" does not accept the token \"%s\"." }],
|
|
138
|
+
"declaration-property-value-disallowed-list": [{ [String.raw`/^(?!(?:-[a-z]+-)?(?:${NAME_PROPERTIES})$)/i`]: [SYSTEM_COLOR] }, { message: "System colors belong in src/theme/." }],
|
|
139
|
+
"selector-class-pattern": ["^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$", { message: "Use snake_case for CSS classes, as in variant_default." }],
|
|
140
|
+
"max-nesting-depth": 2,
|
|
141
|
+
"nesting-selector-no-missing-scoping-root": true,
|
|
142
|
+
"csstools/use-nesting": "always"
|
|
143
|
+
},
|
|
144
|
+
overrides: [{
|
|
145
|
+
files: [path.join(root, "src/theme/**/*.css")],
|
|
146
|
+
rules: {
|
|
147
|
+
"function-disallowed-list": [
|
|
148
|
+
"rgb",
|
|
149
|
+
"rgba",
|
|
150
|
+
"hsl",
|
|
151
|
+
"hsla",
|
|
152
|
+
"hwb",
|
|
153
|
+
"lab",
|
|
154
|
+
"lch",
|
|
155
|
+
"color"
|
|
156
|
+
],
|
|
157
|
+
"value-type-custom-property-required-list": null,
|
|
158
|
+
"declaration-property-value-allowed-list": null,
|
|
159
|
+
"declaration-property-custom-property-allowed-list": null,
|
|
160
|
+
"declaration-property-value-disallowed-list": null
|
|
161
|
+
}
|
|
162
|
+
}]
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
async function checkCss(appRoot) {
|
|
166
|
+
const root = path.resolve(appRoot);
|
|
167
|
+
const config = await defineStylelintConfig(root);
|
|
168
|
+
const [filenames, result] = await Promise.all([filenameDiagnostics(root), stylelint.lint({
|
|
169
|
+
cwd: root,
|
|
170
|
+
files: [CSS_FILES],
|
|
171
|
+
config,
|
|
172
|
+
formatter: "string"
|
|
173
|
+
})]);
|
|
174
|
+
const filenameReport = filenames.map(({ file, message }) => `${file}:1 error project/css-filename: ${message}\n`).join("");
|
|
175
|
+
return {
|
|
176
|
+
report: result.report + filenameReport,
|
|
177
|
+
hasErrors: result.errored || filenames.length > 0
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
export { checkCss, defineStylelintConfig };
|
package/dist/vite.d.mts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { PluginOption, UserConfig, ViteUserConfigFnObject } from "vite-plus";
|
|
2
|
+
import { NitroConfig, NitroModuleInput, PublicAssetDir } from "nitro/types";
|
|
3
|
+
type StaticSecurityHeaders = Record<'strict-transport-security' | 'x-content-type-options' | 'cross-origin-resource-policy', string>;
|
|
4
|
+
type E2eOptions = {
|
|
5
|
+
middleware?: string;
|
|
6
|
+
routes?: string;
|
|
7
|
+
};
|
|
8
|
+
type WorkspaceOptions = {
|
|
9
|
+
dependsOn: string[];
|
|
10
|
+
inputs: string[];
|
|
11
|
+
};
|
|
12
|
+
type StaticAssetDir = PublicAssetDir & {
|
|
13
|
+
baseURL: string;
|
|
14
|
+
};
|
|
15
|
+
type RouteRule = NonNullable<NitroConfig['routeRules']>[string];
|
|
16
|
+
type RunTask = NonNullable<NonNullable<UserConfig['run']>['tasks']>[string];
|
|
17
|
+
type ExtensionContext = {
|
|
18
|
+
target: 'app' | 'test';
|
|
19
|
+
mode: string;
|
|
20
|
+
};
|
|
21
|
+
type SolidAppExtension = {
|
|
22
|
+
plugins?: PluginOption[];
|
|
23
|
+
nitroModules?: NitroModuleInput[];
|
|
24
|
+
};
|
|
25
|
+
type SolidAppOptions = {
|
|
26
|
+
root: string;
|
|
27
|
+
middleware?: string;
|
|
28
|
+
serverSetup?: string;
|
|
29
|
+
e2e?: E2eOptions;
|
|
30
|
+
icons?: Record<string, string>;
|
|
31
|
+
securityHeaders: StaticSecurityHeaders;
|
|
32
|
+
publicAssets?: StaticAssetDir[];
|
|
33
|
+
staticPaths?: string[];
|
|
34
|
+
routeRules?: Record<string, RouteRule>;
|
|
35
|
+
extend?: (context: ExtensionContext) => SolidAppExtension | Promise<SolidAppExtension>;
|
|
36
|
+
workspace?: WorkspaceOptions;
|
|
37
|
+
tasks?: Record<string, RunTask>;
|
|
38
|
+
};
|
|
39
|
+
export declare function defineSolidApp(options: SolidAppOptions): ViteUserConfigFnObject;
|
|
40
|
+
export type { SolidAppOptions };
|