@tamagui/language-service 3.0.0-beta.924.1 → 3.0.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 +25 -134
- package/dist/cjs/check.cjs +85 -10
- package/dist/cjs/check.native.cjs +138 -22
- package/dist/cjs/check.native.js +138 -22
- package/dist/cjs/check.native.js.map +1 -1
- package/dist/cjs/core.cjs +8 -4
- package/dist/cjs/core.native.cjs +10 -9
- package/dist/cjs/core.native.js +10 -9
- package/dist/cjs/core.native.js.map +1 -1
- package/dist/cjs/document.cjs +4 -3
- package/dist/cjs/document.native.cjs +5 -3
- package/dist/cjs/document.native.js +5 -3
- package/dist/cjs/document.native.js.map +1 -1
- package/dist/cjs/extract-estree.native.cjs +2 -6
- package/dist/cjs/extract-estree.native.js +2 -6
- package/dist/cjs/extract-estree.native.js.map +1 -1
- package/dist/cjs/index.cjs +5 -284
- package/dist/cjs/index.native.cjs +5 -395
- package/dist/cjs/index.native.js +5 -395
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/esm/check.mjs +87 -12
- package/dist/esm/check.mjs.map +1 -1
- package/dist/esm/check.native.js +140 -24
- package/dist/esm/check.native.js.map +1 -1
- package/dist/esm/core.mjs +8 -4
- package/dist/esm/core.mjs.map +1 -1
- package/dist/esm/core.native.js +10 -9
- package/dist/esm/core.native.js.map +1 -1
- package/dist/esm/document.mjs +4 -3
- package/dist/esm/document.mjs.map +1 -1
- package/dist/esm/document.native.js +5 -3
- package/dist/esm/document.native.js.map +1 -1
- package/dist/esm/extract-estree.native.js +2 -6
- package/dist/esm/extract-estree.native.js.map +1 -1
- package/dist/esm/index.mjs +5 -279
- package/dist/esm/index.native.js +5 -390
- package/package.json +8 -17
- package/src/check.ts +118 -13
- package/src/core.ts +25 -6
- package/src/document.ts +21 -4
- package/src/index.ts +4 -452
- package/types/check.d.ts +4 -0
- package/types/check.d.ts.map +2 -2
- package/types/core.d.ts +7 -2
- package/types/core.d.ts.map +2 -2
- package/types/document.d.ts +8 -2
- package/types/document.d.ts.map +2 -2
- package/types/index.d.ts +4 -7
- package/types/index.d.ts.map +2 -2
- package/dist/cjs/host.cjs +0 -37
- package/dist/cjs/host.native.cjs +0 -60
- package/dist/cjs/host.native.js +0 -62
- package/dist/cjs/host.native.js.map +0 -1
- package/dist/esm/host.mjs +0 -17
- package/dist/esm/host.mjs.map +0 -1
- package/dist/esm/host.native.js +0 -38
- package/dist/esm/host.native.js.map +0 -1
- package/dist/esm/index.mjs.map +0 -1
- package/dist/esm/index.native.js.map +0 -1
- package/index.cjs +0 -1
- package/src/host.ts +0 -32
- package/types/host.d.ts +0 -10
- package/types/host.d.ts.map +0 -11
package/README.md
CHANGED
|
@@ -1,140 +1,31 @@
|
|
|
1
1
|
# `@tamagui/language-service`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
server
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
3
|
+
Shared flat-value tooling for editors, ESLint, and `tamagui check`.
|
|
4
|
+
|
|
5
|
+
The package reads the `.tamagui/tamagui.config.json` artifact emitted by the
|
|
6
|
+
compiler. Its entry points project the same grammar into completion,
|
|
7
|
+
diagnostic, hover, color, and project-checking APIs:
|
|
8
|
+
|
|
9
|
+
| entry | purpose |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| `@tamagui/language-service` | browser-safe core, document, and extractor APIs |
|
|
12
|
+
| `@tamagui/language-service/core` | tooling for one property and value |
|
|
13
|
+
| `@tamagui/language-service/document` | tooling mapped to source offsets |
|
|
14
|
+
| `@tamagui/language-service/extract-sucrase` | token-stream JSX extraction |
|
|
15
|
+
| `@tamagui/language-service/extract-estree` | ESTree JSX extraction |
|
|
16
|
+
| `@tamagui/language-service/check` | Node project checker used by `tamagui check` |
|
|
17
|
+
|
|
18
|
+
Editor integration is owned by the standalone Rust language server in
|
|
19
|
+
`@tamagui/lsp`. It speaks standard LSP and does not load TypeScript or install a
|
|
20
|
+
tsserver plugin. The VS Code extension is a thin client for the same binary used
|
|
21
|
+
by other editors.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install --save-dev @tamagui/lsp
|
|
24
25
|
```
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
workspace `.vscode/settings.json` file.
|
|
28
|
-
|
|
29
|
-
VS Code also disables automatic suggestions inside strings by default. Enable
|
|
30
|
-
them for TSX if completion should open after typing a space in a value:
|
|
27
|
+
For CI and pre-commit checks:
|
|
31
28
|
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
"[typescriptreact]": {
|
|
35
|
-
"editor.quickSuggestions": {
|
|
36
|
-
"strings": "on"
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
29
|
+
```bash
|
|
30
|
+
tamagui check
|
|
40
31
|
```
|
|
41
|
-
|
|
42
|
-
VS Code's TypeScript provider does not register `:` as a completion trigger.
|
|
43
|
-
The companion Tamagui Language Service extension retriggers suggestions after a
|
|
44
|
-
modifier colon and delegates the resulting request back to this plugin.
|
|
45
|
-
|
|
46
|
-
If the generated config lives elsewhere, set `configPath` relative to the
|
|
47
|
-
TypeScript project:
|
|
48
|
-
|
|
49
|
-
```json
|
|
50
|
-
{
|
|
51
|
-
"compilerOptions": {
|
|
52
|
-
"plugins": [
|
|
53
|
-
{
|
|
54
|
-
"name": "@tamagui/language-service",
|
|
55
|
-
"configPath": ".tamagui/tamagui.config.json"
|
|
56
|
-
}
|
|
57
|
-
]
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
The plugin completes configured values and modifiers in base values and
|
|
63
|
-
conditional clause payloads on components carrying Tamagui's `staticConfig`
|
|
64
|
-
type marker and configurations passed to the core Tamagui `styled()` export.
|
|
65
|
-
TypeScript's contextual prop type remains the authority for whether the host
|
|
66
|
-
accepts that property and value.
|
|
67
|
-
|
|
68
|
-
Modifier suggestions are sorted as state, group, media, container, root theme,
|
|
69
|
-
then platform. `hover:` and `press:` lead the state group. Nested themes remain
|
|
70
|
-
valid `<Theme>` targets but are not flat-value modifiers, so an active
|
|
71
|
-
`dark_blue` theme matches `dark:` and never adds a `dark_blue:` suggestion.
|
|
72
|
-
After a modifier colon, the plugin offers both property values and another
|
|
73
|
-
modifier, so `margin="4 sm:h"` completes to `margin="4 sm:hover:"`.
|
|
74
|
-
State continuations such as `hover:` and `press:` sort first, followed by the
|
|
75
|
-
other modifier categories and configured property values. A finished chain such
|
|
76
|
-
as `margin="4 web:sm:hover:"` still includes its payload tokens in that list.
|
|
77
|
-
Modifier completion traverses a trie derived from the generated config. The
|
|
78
|
-
canonical authoring order is platform, root theme, container, viewport media,
|
|
79
|
-
group state, then subject state. A trie node omits conditions already used,
|
|
80
|
-
aliases of used conditions, additional platforms or root themes, earlier
|
|
81
|
-
categories, and conditions beyond the emitter's five non-platform limit.
|
|
82
|
-
Each category occupies one slot in a clause. For example, `hover:` offers
|
|
83
|
-
payload values and never another subject state such as `press:`, while `sm:`
|
|
84
|
-
never offers another viewport-media modifier.
|
|
85
|
-
Runtime parsing remains order-insensitive for compatibility, but tooling only
|
|
86
|
-
authors the canonical shape. A completed payload resets traversal, so every new
|
|
87
|
-
space-delimited clause starts from the trie root at arbitrary program length.
|
|
88
|
-
|
|
89
|
-
Container conditions include their size: `@sm:` targets the nearest container
|
|
90
|
-
and `@sm/layout:` targets a named container. `@container:` is not a modifier.
|
|
91
|
-
|
|
92
|
-
It does not carry a fallback vocabulary. A missing or invalid generated config
|
|
93
|
-
produces no Tamagui completions, so the editor cannot suggest names the runtime
|
|
94
|
-
config does not define. The generated config is watched and its vocabulary is
|
|
95
|
-
reloaded without restarting tsserver.
|
|
96
|
-
|
|
97
|
-
## Package layout: one engine, many hosts
|
|
98
|
-
|
|
99
|
-
`@tamagui/style-grammar` owns what every value MEANS. This package projects
|
|
100
|
-
that engine into editor- and checker-shaped results, and each host stays a
|
|
101
|
-
thin adapter:
|
|
102
|
-
|
|
103
|
-
| entry | runs in | provides |
|
|
104
|
-
| --- | --- | --- |
|
|
105
|
-
| `@tamagui/language-service` | tsserver | completions, diagnostics, hover (quick info) |
|
|
106
|
-
| `@tamagui/language-service/core` | anywhere (browser-safe) | `createStyleTooling(configJson)`: completions, diagnostics, annotations, hover, color swatches for one prop/value |
|
|
107
|
-
| `@tamagui/language-service/document` | anywhere (browser-safe) | `createDocumentStyleTooling(tooling, extract)`: the same, mapped to file offsets |
|
|
108
|
-
| `@tamagui/language-service/extract-sucrase` | anywhere (browser-safe) | token-stream site extraction; inject your own sucrase `parse`/`TokenType` so bundles never duplicate it |
|
|
109
|
-
| `@tamagui/language-service/extract-estree` | anywhere | the same site contract from any ESTree program (eslint, oxc-parser) |
|
|
110
|
-
| `@tamagui/language-service/check` | node | `checkStyleFiles` + `formatCheckResults`, the engine behind `tamagui check` |
|
|
111
|
-
|
|
112
|
-
Every path takes the same input: the `.tamagui/tamagui.config.json` artifact
|
|
113
|
-
the compiler emits. `core`, `document`, and `extract-sucrase` have no node,
|
|
114
|
-
typescript, or sucrase imports — bundled together they are ~15KB gzipped — so
|
|
115
|
-
an in-browser IDE embeds them directly:
|
|
116
|
-
|
|
117
|
-
```ts
|
|
118
|
-
import { createStyleTooling } from '@tamagui/language-service/core'
|
|
119
|
-
import { createDocumentStyleTooling } from '@tamagui/language-service/document'
|
|
120
|
-
import { createSucraseStyleSiteExtractor } from '@tamagui/language-service/extract-sucrase'
|
|
121
|
-
import { parse } from 'sucrase/dist/parser/index.js'
|
|
122
|
-
import { TokenType } from 'sucrase/dist/parser/tokenizer/types.js'
|
|
123
|
-
|
|
124
|
-
const tooling = createStyleTooling(configJson)
|
|
125
|
-
const document = createDocumentStyleTooling(
|
|
126
|
-
tooling,
|
|
127
|
-
createSucraseStyleSiteExtractor({ parse, TokenType }, {
|
|
128
|
-
isStyleProp: (name) => tooling.isStyleProp(name),
|
|
129
|
-
})
|
|
130
|
-
)
|
|
131
|
-
document.completionsAt(source, offset)
|
|
132
|
-
document.diagnostics(source)
|
|
133
|
-
document.hoverAt(source, offset)
|
|
134
|
-
document.colors(source)
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
The VS Code extension (`code/core/language-service-vscode`) contributes this
|
|
138
|
-
plugin through `typescriptServerPlugins` (zero per-project tsconfig setup),
|
|
139
|
-
adds inline color swatches through the document API, and retriggers
|
|
140
|
-
completions after modifier colons.
|
package/dist/cjs/check.cjs
CHANGED
|
@@ -28,6 +28,7 @@ __export(check_exports, {
|
|
|
28
28
|
module.exports = __toCommonJS(check_exports);
|
|
29
29
|
var import_node_fs = require("node:fs");
|
|
30
30
|
var import_node_path = require("node:path");
|
|
31
|
+
var import_node_child_process = require("node:child_process");
|
|
31
32
|
var import_parser = require("sucrase/dist/parser/index.js");
|
|
32
33
|
var import_types = require("sucrase/dist/parser/tokenizer/types.js");
|
|
33
34
|
var import_core = require("./core.cjs");
|
|
@@ -45,18 +46,29 @@ const skippedDirectories = /* @__PURE__ */ new Set([
|
|
|
45
46
|
".expo",
|
|
46
47
|
".tamagui"
|
|
47
48
|
]);
|
|
49
|
+
const projectMarkers = [
|
|
50
|
+
"tamagui.build.ts",
|
|
51
|
+
"tamagui.build.tsx",
|
|
52
|
+
"tamagui.build.js",
|
|
53
|
+
"tamagui.build.mjs",
|
|
54
|
+
"tamagui.build.cjs"
|
|
55
|
+
];
|
|
48
56
|
var MissingConfigArtifactError = class extends Error {
|
|
49
57
|
constructor(configPath) {
|
|
50
58
|
super(`no Tamagui config artifact at ${configPath} \u2014 run your dev server or \`tamagui generate\` once so the compiler emits it`);
|
|
51
59
|
this.name = "MissingConfigArtifactError";
|
|
52
60
|
}
|
|
53
61
|
};
|
|
54
|
-
function walkSourceFiles(directory, results) {
|
|
62
|
+
function walkSourceFiles(directory, root, results, skippedProjects) {
|
|
55
63
|
for (const entry of (0, import_node_fs.readdirSync)(directory, { withFileTypes: true })) {
|
|
56
64
|
if (entry.isDirectory()) {
|
|
57
|
-
if (
|
|
58
|
-
|
|
65
|
+
if (skippedDirectories.has(entry.name) || entry.name.startsWith(".")) continue;
|
|
66
|
+
const child = (0, import_node_path.join)(directory, entry.name);
|
|
67
|
+
if (projectMarkers.some((marker) => (0, import_node_fs.existsSync)((0, import_node_path.join)(child, marker))) || (0, import_node_fs.existsSync)((0, import_node_path.join)(child, ".tamagui", "tamagui.config.json"))) {
|
|
68
|
+
skippedProjects.push((0, import_node_path.relative)(root, child));
|
|
69
|
+
continue;
|
|
59
70
|
}
|
|
71
|
+
walkSourceFiles(child, root, results, skippedProjects);
|
|
60
72
|
continue;
|
|
61
73
|
}
|
|
62
74
|
if (sourceExtensions.test(entry.name)) results.push((0, import_node_path.join)(directory, entry.name));
|
|
@@ -69,23 +81,82 @@ function createProjectExtractor(isStyleProp) {
|
|
|
69
81
|
}, { isStyleProp });
|
|
70
82
|
}
|
|
71
83
|
function checkStyleFiles(options) {
|
|
72
|
-
const
|
|
84
|
+
const root = (0, import_node_path.resolve)(options.root);
|
|
85
|
+
const configPath = options.configPath ?? (0, import_node_path.join)(root, ".tamagui", "tamagui.config.json");
|
|
73
86
|
let contents;
|
|
74
87
|
try {
|
|
75
88
|
contents = (0, import_node_fs.readFileSync)(configPath, "utf8");
|
|
76
89
|
} catch {
|
|
77
90
|
throw new MissingConfigArtifactError(configPath);
|
|
78
91
|
}
|
|
79
|
-
const tooling = (0, import_core.createStyleTooling)(JSON.parse(contents));
|
|
92
|
+
const tooling = (0, import_core.createStyleTooling)(JSON.parse(contents), { strictPayloads: options.strict });
|
|
80
93
|
if (!tooling) throw new MissingConfigArtifactError(configPath);
|
|
81
|
-
const document = (0, import_document.createDocumentStyleTooling)(tooling, createProjectExtractor((name) => tooling.isStyleProp(name)));
|
|
94
|
+
const document = (0, import_document.createDocumentStyleTooling)(tooling, createProjectExtractor((name) => tooling.isStyleProp(name)), { strictPayloads: options.strict });
|
|
82
95
|
let files;
|
|
96
|
+
const skippedProjects = [];
|
|
83
97
|
if (options.files) {
|
|
84
98
|
files = [...options.files];
|
|
85
99
|
} else {
|
|
86
100
|
files = [];
|
|
87
|
-
|
|
101
|
+
const insideGit = (0, import_node_child_process.spawnSync)("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
102
|
+
cwd: root,
|
|
103
|
+
encoding: "utf8"
|
|
104
|
+
});
|
|
105
|
+
if (insideGit.status === 0) {
|
|
106
|
+
const listed = (0, import_node_child_process.spawnSync)("git", [
|
|
107
|
+
"ls-files",
|
|
108
|
+
"--cached",
|
|
109
|
+
"--others",
|
|
110
|
+
"--exclude-standard",
|
|
111
|
+
"-z",
|
|
112
|
+
"--",
|
|
113
|
+
"*.tsx",
|
|
114
|
+
"*.jsx"
|
|
115
|
+
], {
|
|
116
|
+
cwd: root,
|
|
117
|
+
encoding: "utf8",
|
|
118
|
+
maxBuffer: 64 * 1024 * 1024
|
|
119
|
+
});
|
|
120
|
+
if (listed.error) throw listed.error;
|
|
121
|
+
if (listed.status !== 0) {
|
|
122
|
+
throw new Error(listed.stderr.trim() || "git ls-files failed");
|
|
123
|
+
}
|
|
124
|
+
const skipped = /* @__PURE__ */ new Set();
|
|
125
|
+
const projectByDirectory = /* @__PURE__ */ new Map();
|
|
126
|
+
for (const relativeFile of listed.stdout.split("\0")) {
|
|
127
|
+
if (!relativeFile) continue;
|
|
128
|
+
const file = (0, import_node_path.join)(root, relativeFile);
|
|
129
|
+
if (!(0, import_node_fs.existsSync)(file)) continue;
|
|
130
|
+
let directory = (0, import_node_path.dirname)(file);
|
|
131
|
+
let nestedProject = null;
|
|
132
|
+
const visited = [];
|
|
133
|
+
while (directory !== root) {
|
|
134
|
+
if (projectByDirectory.has(directory)) {
|
|
135
|
+
nestedProject = projectByDirectory.get(directory) ?? null;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
visited.push(directory);
|
|
139
|
+
if (projectMarkers.some((marker) => (0, import_node_fs.existsSync)((0, import_node_path.join)(directory, marker))) || (0, import_node_fs.existsSync)((0, import_node_path.join)(directory, ".tamagui", "tamagui.config.json"))) {
|
|
140
|
+
nestedProject = directory;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
directory = (0, import_node_path.dirname)(directory);
|
|
144
|
+
}
|
|
145
|
+
for (const visitedDirectory of visited) {
|
|
146
|
+
projectByDirectory.set(visitedDirectory, nestedProject);
|
|
147
|
+
}
|
|
148
|
+
if (nestedProject) {
|
|
149
|
+
skipped.add((0, import_node_path.relative)(root, nestedProject));
|
|
150
|
+
} else {
|
|
151
|
+
files.push(file);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
skippedProjects.push(...skipped);
|
|
155
|
+
} else {
|
|
156
|
+
walkSourceFiles(root, root, files, skippedProjects);
|
|
157
|
+
}
|
|
88
158
|
files.sort();
|
|
159
|
+
skippedProjects.sort();
|
|
89
160
|
}
|
|
90
161
|
const checked = [];
|
|
91
162
|
let diagnosticCount = 0;
|
|
@@ -98,14 +169,14 @@ function checkStyleFiles(options) {
|
|
|
98
169
|
}
|
|
99
170
|
let diagnostics;
|
|
100
171
|
try {
|
|
101
|
-
diagnostics = document.diagnostics(source);
|
|
172
|
+
diagnostics = document.diagnostics(source, void 0, { strictPayloads: options.strict });
|
|
102
173
|
} catch {
|
|
103
174
|
continue;
|
|
104
175
|
}
|
|
105
176
|
if (diagnostics.length === 0) continue;
|
|
106
177
|
diagnosticCount += diagnostics.length;
|
|
107
178
|
checked.push({
|
|
108
|
-
file: (0, import_node_path.relative)(
|
|
179
|
+
file: (0, import_node_path.relative)(root, file),
|
|
109
180
|
source,
|
|
110
181
|
diagnostics
|
|
111
182
|
});
|
|
@@ -113,7 +184,8 @@ function checkStyleFiles(options) {
|
|
|
113
184
|
return {
|
|
114
185
|
files: checked,
|
|
115
186
|
checkedFileCount: files.length,
|
|
116
|
-
diagnosticCount
|
|
187
|
+
diagnosticCount,
|
|
188
|
+
skippedProjects
|
|
117
189
|
};
|
|
118
190
|
}
|
|
119
191
|
const ansi = {
|
|
@@ -166,6 +238,9 @@ function formatCheckResults(result, options = {}) {
|
|
|
166
238
|
output.push("");
|
|
167
239
|
}
|
|
168
240
|
}
|
|
241
|
+
if (result.skippedProjects.length > 0) {
|
|
242
|
+
output.push(paint.dim(`Skipped nested Tamagui projects: ${result.skippedProjects.join(", ")}`));
|
|
243
|
+
}
|
|
169
244
|
const summary = result.diagnosticCount === 0 ? `${paint.bold("✓")} ${result.checkedFileCount} files, no flat value problems` : `${paint.red(paint.bold(`\u2717 ${result.diagnosticCount} problem${result.diagnosticCount === 1 ? "" : "s"}`))} in ${result.files.length} file${result.files.length === 1 ? "" : "s"} ${paint.dim(`(${result.checkedFileCount} checked)`)}`;
|
|
170
245
|
output.push(summary);
|
|
171
246
|
return output.join("\n");
|
|
@@ -30,6 +30,7 @@ __export(check_exports, {
|
|
|
30
30
|
module.exports = __toCommonJS(check_exports);
|
|
31
31
|
var import_fs = require("fs");
|
|
32
32
|
var import_path = require("path");
|
|
33
|
+
var import_child_process = require("child_process");
|
|
33
34
|
var import_parser = require("sucrase/dist/parser/index.js");
|
|
34
35
|
var import_types = require("sucrase/dist/parser/tokenizer/types.js");
|
|
35
36
|
var import_core = require("./core.native.js");
|
|
@@ -146,6 +147,13 @@ var skippedDirectories = /* @__PURE__ */ new Set([
|
|
|
146
147
|
".expo",
|
|
147
148
|
".tamagui"
|
|
148
149
|
]);
|
|
150
|
+
var projectMarkers = [
|
|
151
|
+
"tamagui.build.ts",
|
|
152
|
+
"tamagui.build.tsx",
|
|
153
|
+
"tamagui.build.js",
|
|
154
|
+
"tamagui.build.mjs",
|
|
155
|
+
"tamagui.build.cjs"
|
|
156
|
+
];
|
|
149
157
|
var MissingConfigArtifactError = /* @__PURE__ */ (function(Error1) {
|
|
150
158
|
"use strict";
|
|
151
159
|
_inherits(MissingConfigArtifactError2, Error1);
|
|
@@ -158,19 +166,26 @@ var MissingConfigArtifactError = /* @__PURE__ */ (function(Error1) {
|
|
|
158
166
|
}
|
|
159
167
|
return MissingConfigArtifactError2;
|
|
160
168
|
})(_wrap_native_super(Error));
|
|
161
|
-
function walkSourceFiles(directory, results) {
|
|
169
|
+
function walkSourceFiles(directory, root, results, skippedProjects) {
|
|
162
170
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
163
171
|
try {
|
|
164
|
-
|
|
172
|
+
var _loop = function() {
|
|
165
173
|
var entry = _step.value;
|
|
166
174
|
if (entry.isDirectory()) {
|
|
167
|
-
if (
|
|
168
|
-
|
|
175
|
+
if (skippedDirectories.has(entry.name) || entry.name.startsWith(".")) return "continue";
|
|
176
|
+
var child = (0, import_path.join)(directory, entry.name);
|
|
177
|
+
if (projectMarkers.some(function(marker) {
|
|
178
|
+
return (0, import_fs.existsSync)((0, import_path.join)(child, marker));
|
|
179
|
+
}) || (0, import_fs.existsSync)((0, import_path.join)(child, ".tamagui", "tamagui.config.json"))) {
|
|
180
|
+
skippedProjects.push((0, import_path.relative)(root, child));
|
|
181
|
+
return "continue";
|
|
169
182
|
}
|
|
170
|
-
|
|
183
|
+
walkSourceFiles(child, root, results, skippedProjects);
|
|
184
|
+
return "continue";
|
|
171
185
|
}
|
|
172
186
|
if (sourceExtensions.test(entry.name)) results.push((0, import_path.join)(directory, entry.name));
|
|
173
|
-
}
|
|
187
|
+
};
|
|
188
|
+
for (var _iterator = (0, import_fs.readdirSync)(directory, { withFileTypes: true })[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) _loop();
|
|
174
189
|
} catch (err) {
|
|
175
190
|
_didIteratorError = true;
|
|
176
191
|
_iteratorError = err;
|
|
@@ -193,33 +208,130 @@ function createProjectExtractor(isStyleProp) {
|
|
|
193
208
|
}, { isStyleProp });
|
|
194
209
|
}
|
|
195
210
|
function checkStyleFiles(options) {
|
|
211
|
+
var root = (0, import_path.resolve)(options.root);
|
|
196
212
|
var _options_configPath;
|
|
197
|
-
var configPath = (_options_configPath = options.configPath) !== null && _options_configPath !== void 0 ? _options_configPath : (0, import_path.join)(
|
|
213
|
+
var configPath = (_options_configPath = options.configPath) !== null && _options_configPath !== void 0 ? _options_configPath : (0, import_path.join)(root, ".tamagui", "tamagui.config.json");
|
|
198
214
|
var contents;
|
|
199
215
|
try {
|
|
200
216
|
contents = (0, import_fs.readFileSync)(configPath, "utf8");
|
|
201
217
|
} catch (e) {
|
|
202
218
|
throw new MissingConfigArtifactError(configPath);
|
|
203
219
|
}
|
|
204
|
-
var tooling = (0, import_core.createStyleTooling)(JSON.parse(contents));
|
|
220
|
+
var tooling = (0, import_core.createStyleTooling)(JSON.parse(contents), { strictPayloads: options.strict });
|
|
205
221
|
if (!tooling) throw new MissingConfigArtifactError(configPath);
|
|
206
222
|
var document = (0, import_document.createDocumentStyleTooling)(tooling, createProjectExtractor(function(name) {
|
|
207
223
|
return tooling.isStyleProp(name);
|
|
208
|
-
}));
|
|
224
|
+
}), { strictPayloads: options.strict });
|
|
209
225
|
var files;
|
|
226
|
+
var skippedProjects = [];
|
|
210
227
|
if (options.files) {
|
|
211
228
|
files = [...options.files];
|
|
212
229
|
} else {
|
|
213
230
|
files = [];
|
|
214
|
-
|
|
231
|
+
var insideGit = (0, import_child_process.spawnSync)("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
232
|
+
cwd: root,
|
|
233
|
+
encoding: "utf8"
|
|
234
|
+
});
|
|
235
|
+
if (insideGit.status === 0) {
|
|
236
|
+
var listed = (0, import_child_process.spawnSync)("git", [
|
|
237
|
+
"ls-files",
|
|
238
|
+
"--cached",
|
|
239
|
+
"--others",
|
|
240
|
+
"--exclude-standard",
|
|
241
|
+
"-z",
|
|
242
|
+
"--",
|
|
243
|
+
"*.tsx",
|
|
244
|
+
"*.jsx"
|
|
245
|
+
], {
|
|
246
|
+
cwd: root,
|
|
247
|
+
encoding: "utf8",
|
|
248
|
+
maxBuffer: 64 * 1024 * 1024
|
|
249
|
+
});
|
|
250
|
+
if (listed.error) throw listed.error;
|
|
251
|
+
if (listed.status !== 0) {
|
|
252
|
+
throw new Error(listed.stderr.trim() || "git ls-files failed");
|
|
253
|
+
}
|
|
254
|
+
var skipped = /* @__PURE__ */ new Set();
|
|
255
|
+
var projectByDirectory = /* @__PURE__ */ new Map();
|
|
256
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
257
|
+
try {
|
|
258
|
+
var _loop = function() {
|
|
259
|
+
var relativeFile = _step.value;
|
|
260
|
+
if (!relativeFile) return "continue";
|
|
261
|
+
var file2 = (0, import_path.join)(root, relativeFile);
|
|
262
|
+
if (!(0, import_fs.existsSync)(file2)) return "continue";
|
|
263
|
+
var directory = (0, import_path.dirname)(file2);
|
|
264
|
+
var nestedProject = null;
|
|
265
|
+
var visited = [];
|
|
266
|
+
while (directory !== root) {
|
|
267
|
+
if (projectByDirectory.has(directory)) {
|
|
268
|
+
var _projectByDirectory_get;
|
|
269
|
+
nestedProject = (_projectByDirectory_get = projectByDirectory.get(directory)) !== null && _projectByDirectory_get !== void 0 ? _projectByDirectory_get : null;
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
visited.push(directory);
|
|
273
|
+
if (projectMarkers.some(function(marker) {
|
|
274
|
+
return (0, import_fs.existsSync)((0, import_path.join)(directory, marker));
|
|
275
|
+
}) || (0, import_fs.existsSync)((0, import_path.join)(directory, ".tamagui", "tamagui.config.json"))) {
|
|
276
|
+
nestedProject = directory;
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
directory = (0, import_path.dirname)(directory);
|
|
280
|
+
}
|
|
281
|
+
var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = void 0;
|
|
282
|
+
try {
|
|
283
|
+
for (var _iterator2 = visited[Symbol.iterator](), _step12; !(_iteratorNormalCompletion2 = (_step12 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
284
|
+
var visitedDirectory = _step12.value;
|
|
285
|
+
projectByDirectory.set(visitedDirectory, nestedProject);
|
|
286
|
+
}
|
|
287
|
+
} catch (err) {
|
|
288
|
+
_didIteratorError2 = true;
|
|
289
|
+
_iteratorError2 = err;
|
|
290
|
+
} finally {
|
|
291
|
+
try {
|
|
292
|
+
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
|
|
293
|
+
_iterator2.return();
|
|
294
|
+
}
|
|
295
|
+
} finally {
|
|
296
|
+
if (_didIteratorError2) {
|
|
297
|
+
throw _iteratorError2;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (nestedProject) {
|
|
302
|
+
skipped.add((0, import_path.relative)(root, nestedProject));
|
|
303
|
+
} else {
|
|
304
|
+
files.push(file2);
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
for (var _iterator = listed.stdout.split("\0")[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) _loop();
|
|
308
|
+
} catch (err) {
|
|
309
|
+
_didIteratorError = true;
|
|
310
|
+
_iteratorError = err;
|
|
311
|
+
} finally {
|
|
312
|
+
try {
|
|
313
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
314
|
+
_iterator.return();
|
|
315
|
+
}
|
|
316
|
+
} finally {
|
|
317
|
+
if (_didIteratorError) {
|
|
318
|
+
throw _iteratorError;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
skippedProjects.push(...skipped);
|
|
323
|
+
} else {
|
|
324
|
+
walkSourceFiles(root, root, files, skippedProjects);
|
|
325
|
+
}
|
|
215
326
|
files.sort();
|
|
327
|
+
skippedProjects.sort();
|
|
216
328
|
}
|
|
217
329
|
var checked = [];
|
|
218
330
|
var diagnosticCount = 0;
|
|
219
|
-
var
|
|
331
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = void 0;
|
|
220
332
|
try {
|
|
221
|
-
for (var
|
|
222
|
-
var file =
|
|
333
|
+
for (var _iterator1 = files[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
|
|
334
|
+
var file = _step1.value;
|
|
223
335
|
var source = void 0;
|
|
224
336
|
try {
|
|
225
337
|
source = (0, import_fs.readFileSync)(file, "utf8");
|
|
@@ -228,36 +340,37 @@ function checkStyleFiles(options) {
|
|
|
228
340
|
}
|
|
229
341
|
var diagnostics = void 0;
|
|
230
342
|
try {
|
|
231
|
-
diagnostics = document.diagnostics(source);
|
|
343
|
+
diagnostics = document.diagnostics(source, void 0, { strictPayloads: options.strict });
|
|
232
344
|
} catch (e) {
|
|
233
345
|
continue;
|
|
234
346
|
}
|
|
235
347
|
if (diagnostics.length === 0) continue;
|
|
236
348
|
diagnosticCount += diagnostics.length;
|
|
237
349
|
checked.push({
|
|
238
|
-
file: (0, import_path.relative)(
|
|
350
|
+
file: (0, import_path.relative)(root, file),
|
|
239
351
|
source,
|
|
240
352
|
diagnostics
|
|
241
353
|
});
|
|
242
354
|
}
|
|
243
355
|
} catch (err) {
|
|
244
|
-
|
|
245
|
-
|
|
356
|
+
_didIteratorError1 = true;
|
|
357
|
+
_iteratorError1 = err;
|
|
246
358
|
} finally {
|
|
247
359
|
try {
|
|
248
|
-
if (!
|
|
249
|
-
|
|
360
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
361
|
+
_iterator1.return();
|
|
250
362
|
}
|
|
251
363
|
} finally {
|
|
252
|
-
if (
|
|
253
|
-
throw
|
|
364
|
+
if (_didIteratorError1) {
|
|
365
|
+
throw _iteratorError1;
|
|
254
366
|
}
|
|
255
367
|
}
|
|
256
368
|
}
|
|
257
369
|
return {
|
|
258
370
|
files: checked,
|
|
259
371
|
checkedFileCount: files.length,
|
|
260
|
-
diagnosticCount
|
|
372
|
+
diagnosticCount,
|
|
373
|
+
skippedProjects
|
|
261
374
|
};
|
|
262
375
|
}
|
|
263
376
|
var ansi = {
|
|
@@ -362,6 +475,9 @@ function formatCheckResults(result) {
|
|
|
362
475
|
}
|
|
363
476
|
}
|
|
364
477
|
}
|
|
478
|
+
if (result.skippedProjects.length > 0) {
|
|
479
|
+
output.push(paint.dim(`Skipped nested Tamagui projects: ${result.skippedProjects.join(", ")}`));
|
|
480
|
+
}
|
|
365
481
|
var summary = result.diagnosticCount === 0 ? `${paint.bold("✓")} ${result.checkedFileCount} files, no flat value problems` : `${paint.red(paint.bold(`\u2717 ${result.diagnosticCount} problem${result.diagnosticCount === 1 ? "" : "s"}`))} in ${result.files.length} file${result.files.length === 1 ? "" : "s"} ${paint.dim(`(${result.checkedFileCount} checked)`)}`;
|
|
366
482
|
output.push(summary);
|
|
367
483
|
return output.join("\n");
|