@tamagui/language-service 0.0.0-bootstrap.0 → 3.0.0-beta.637.1
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 +140 -1
- package/dist/cjs/check.cjs +173 -0
- package/dist/cjs/check.native.cjs +369 -0
- package/dist/cjs/check.native.js +371 -0
- package/dist/cjs/check.native.js.map +1 -0
- package/dist/cjs/core.cjs +221 -0
- package/dist/cjs/core.native.cjs +305 -0
- package/dist/cjs/core.native.js +307 -0
- package/dist/cjs/core.native.js.map +1 -0
- package/dist/cjs/document.cjs +82 -0
- package/dist/cjs/document.native.cjs +158 -0
- package/dist/cjs/document.native.js +160 -0
- package/dist/cjs/document.native.js.map +1 -0
- package/dist/cjs/extract-estree.cjs +193 -0
- package/dist/cjs/extract-estree.native.cjs +296 -0
- package/dist/cjs/extract-estree.native.js +298 -0
- package/dist/cjs/extract-estree.native.js.map +1 -0
- package/dist/cjs/extract-sucrase.cjs +222 -0
- package/dist/cjs/extract-sucrase.native.cjs +256 -0
- package/dist/cjs/extract-sucrase.native.js +258 -0
- package/dist/cjs/extract-sucrase.native.js.map +1 -0
- package/dist/cjs/host.cjs +38 -0
- package/dist/cjs/host.native.cjs +61 -0
- package/dist/cjs/host.native.js +63 -0
- package/dist/cjs/host.native.js.map +1 -0
- package/dist/cjs/index.cjs +301 -0
- package/dist/cjs/index.native.cjs +414 -0
- package/dist/cjs/index.native.js +416 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/esm/check.mjs +148 -0
- package/dist/esm/check.mjs.map +1 -0
- package/dist/esm/check.native.js +342 -0
- package/dist/esm/check.native.js.map +1 -0
- package/dist/esm/core.mjs +198 -0
- package/dist/esm/core.mjs.map +1 -0
- package/dist/esm/core.native.js +280 -0
- package/dist/esm/core.native.js.map +1 -0
- package/dist/esm/document.mjs +61 -0
- package/dist/esm/document.mjs.map +1 -0
- package/dist/esm/document.native.js +135 -0
- package/dist/esm/document.native.js.map +1 -0
- package/dist/esm/extract-estree.mjs +172 -0
- package/dist/esm/extract-estree.mjs.map +1 -0
- package/dist/esm/extract-estree.native.js +273 -0
- package/dist/esm/extract-estree.native.js.map +1 -0
- package/dist/esm/extract-sucrase.mjs +201 -0
- package/dist/esm/extract-sucrase.mjs.map +1 -0
- package/dist/esm/extract-sucrase.native.js +233 -0
- package/dist/esm/extract-sucrase.native.js.map +1 -0
- package/dist/esm/host.mjs +17 -0
- package/dist/esm/host.mjs.map +1 -0
- package/dist/esm/host.native.js +38 -0
- package/dist/esm/host.native.js.map +1 -0
- package/dist/esm/index.mjs +281 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +392 -0
- package/dist/esm/index.native.js.map +1 -0
- package/index.cjs +1 -0
- package/package.json +79 -7
- package/src/check.ts +204 -0
- package/src/core.ts +355 -0
- package/src/document.ts +140 -0
- package/src/extract-estree.ts +251 -0
- package/src/extract-sucrase.ts +308 -0
- package/src/host.ts +32 -0
- package/src/index.ts +452 -0
- package/types/check.d.ts +31 -0
- package/types/check.d.ts.map +11 -0
- package/types/core.d.ts +68 -0
- package/types/core.d.ts.map +11 -0
- package/types/document.d.ts +42 -0
- package/types/document.d.ts.map +11 -0
- package/types/extract-estree.d.ts +19 -0
- package/types/extract-estree.d.ts.map +11 -0
- package/types/extract-sucrase.d.ts +26 -0
- package/types/extract-sucrase.d.ts.map +11 -0
- package/types/host.d.ts +10 -0
- package/types/host.d.ts.map +11 -0
- package/types/index.d.ts +9 -0
- package/types/index.d.ts.map +11 -0
package/README.md
CHANGED
|
@@ -1 +1,140 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@tamagui/language-service`
|
|
2
|
+
|
|
3
|
+
TypeScript language-service completions for Tamagui flat style values. The
|
|
4
|
+
plugin reads the `.tamagui/tamagui.config.json` file emitted from the active
|
|
5
|
+
Tamagui runtime config, then delegates its vocabulary, parsing, and
|
|
6
|
+
property-family validation to `@tamagui/style-grammar`.
|
|
7
|
+
|
|
8
|
+
```json
|
|
9
|
+
{
|
|
10
|
+
"compilerOptions": {
|
|
11
|
+
"plugins": [{ "name": "@tamagui/language-service" }]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
VS Code must also be able to resolve the plugin package. Select the workspace
|
|
17
|
+
TypeScript version, or add this machine setting and restart the TypeScript
|
|
18
|
+
server:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"js/ts.tsserver.pluginPaths": ["node_modules"]
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`js/ts.tsserver.pluginPaths` is machine-scoped, so VS Code ignores it in a
|
|
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:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"[typescriptreact]": {
|
|
35
|
+
"editor.quickSuggestions": {
|
|
36
|
+
"strings": "on"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
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.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all) __defProp(target, name, {
|
|
8
|
+
get: all[name],
|
|
9
|
+
enumerable: true
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
15
|
+
get: () => from[key],
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
var check_exports = {};
|
|
23
|
+
__export(check_exports, {
|
|
24
|
+
MissingConfigArtifactError: () => MissingConfigArtifactError,
|
|
25
|
+
checkStyleFiles: () => checkStyleFiles,
|
|
26
|
+
createProjectExtractor: () => createProjectExtractor,
|
|
27
|
+
formatCheckResults: () => formatCheckResults
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(check_exports);
|
|
30
|
+
var import_node_fs = require("node:fs");
|
|
31
|
+
var import_node_path = require("node:path");
|
|
32
|
+
var import_parser = require("sucrase/dist/parser/index.js");
|
|
33
|
+
var import_types = require("sucrase/dist/parser/tokenizer/types.js");
|
|
34
|
+
var import_core = require("./core.cjs");
|
|
35
|
+
var import_document = require("./document.cjs");
|
|
36
|
+
var import_extract_sucrase = require("./extract-sucrase.cjs");
|
|
37
|
+
const sourceExtensions = /\.(tsx|jsx)$/;
|
|
38
|
+
const skippedDirectories = /* @__PURE__ */ new Set([
|
|
39
|
+
"node_modules",
|
|
40
|
+
"dist",
|
|
41
|
+
"build",
|
|
42
|
+
"out",
|
|
43
|
+
"coverage",
|
|
44
|
+
".git",
|
|
45
|
+
".next",
|
|
46
|
+
".expo",
|
|
47
|
+
".tamagui"
|
|
48
|
+
]);
|
|
49
|
+
var MissingConfigArtifactError = class extends Error {
|
|
50
|
+
constructor(configPath) {
|
|
51
|
+
super(`no Tamagui config artifact at ${configPath} \u2014 run your dev server or \`tamagui generate\` once so the compiler emits it`);
|
|
52
|
+
this.name = "MissingConfigArtifactError";
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
function walkSourceFiles(directory, results) {
|
|
56
|
+
for (const entry of (0, import_node_fs.readdirSync)(directory, { withFileTypes: true })) {
|
|
57
|
+
if (entry.isDirectory()) {
|
|
58
|
+
if (!skippedDirectories.has(entry.name) && !entry.name.startsWith(".")) {
|
|
59
|
+
walkSourceFiles((0, import_node_path.join)(directory, entry.name), results);
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (sourceExtensions.test(entry.name)) results.push((0, import_node_path.join)(directory, entry.name));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function createProjectExtractor(isStyleProp) {
|
|
67
|
+
return (0, import_extract_sucrase.createSucraseStyleSiteExtractor)({
|
|
68
|
+
parse: import_parser.parse,
|
|
69
|
+
TokenType: import_types.TokenType
|
|
70
|
+
}, { isStyleProp });
|
|
71
|
+
}
|
|
72
|
+
function checkStyleFiles(options) {
|
|
73
|
+
const configPath = options.configPath ?? (0, import_node_path.join)(options.root, ".tamagui", "tamagui.config.json");
|
|
74
|
+
let contents;
|
|
75
|
+
try {
|
|
76
|
+
contents = (0, import_node_fs.readFileSync)(configPath, "utf8");
|
|
77
|
+
} catch {
|
|
78
|
+
throw new MissingConfigArtifactError(configPath);
|
|
79
|
+
}
|
|
80
|
+
const tooling = (0, import_core.createStyleTooling)(JSON.parse(contents));
|
|
81
|
+
if (!tooling) throw new MissingConfigArtifactError(configPath);
|
|
82
|
+
const document = (0, import_document.createDocumentStyleTooling)(tooling, createProjectExtractor((name) => tooling.isStyleProp(name)));
|
|
83
|
+
let files;
|
|
84
|
+
if (options.files) {
|
|
85
|
+
files = [...options.files];
|
|
86
|
+
} else {
|
|
87
|
+
files = [];
|
|
88
|
+
walkSourceFiles(options.root, files);
|
|
89
|
+
files.sort();
|
|
90
|
+
}
|
|
91
|
+
const checked = [];
|
|
92
|
+
let diagnosticCount = 0;
|
|
93
|
+
for (const file of files) {
|
|
94
|
+
let source;
|
|
95
|
+
try {
|
|
96
|
+
source = (0, import_node_fs.readFileSync)(file, "utf8");
|
|
97
|
+
} catch {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
let diagnostics;
|
|
101
|
+
try {
|
|
102
|
+
diagnostics = document.diagnostics(source);
|
|
103
|
+
} catch {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (diagnostics.length === 0) continue;
|
|
107
|
+
diagnosticCount += diagnostics.length;
|
|
108
|
+
checked.push({
|
|
109
|
+
file: (0, import_node_path.relative)(options.root, file),
|
|
110
|
+
source,
|
|
111
|
+
diagnostics
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
files: checked,
|
|
116
|
+
checkedFileCount: files.length,
|
|
117
|
+
diagnosticCount
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
const ansi = {
|
|
121
|
+
red: (text) => `\x1B[31m${text}\x1B[39m`,
|
|
122
|
+
dim: (text) => `\x1B[2m${text}\x1B[22m`,
|
|
123
|
+
bold: (text) => `\x1B[1m${text}\x1B[22m`,
|
|
124
|
+
cyan: (text) => `\x1B[36m${text}\x1B[39m`
|
|
125
|
+
};
|
|
126
|
+
const plain = {
|
|
127
|
+
red: (text) => text,
|
|
128
|
+
dim: (text) => text,
|
|
129
|
+
bold: (text) => text,
|
|
130
|
+
cyan: (text) => text
|
|
131
|
+
};
|
|
132
|
+
function lineStarts(source) {
|
|
133
|
+
const starts = [0];
|
|
134
|
+
for (let index = 0; index < source.length; index++) {
|
|
135
|
+
if (source.charCodeAt(index) === 10) starts.push(index + 1);
|
|
136
|
+
}
|
|
137
|
+
return starts;
|
|
138
|
+
}
|
|
139
|
+
function positionOf(starts, offset) {
|
|
140
|
+
let low = 0;
|
|
141
|
+
let high = starts.length - 1;
|
|
142
|
+
while (low < high) {
|
|
143
|
+
const mid = low + high + 1 >> 1;
|
|
144
|
+
if (starts[mid] <= offset) low = mid;
|
|
145
|
+
else high = mid - 1;
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
line: low,
|
|
149
|
+
column: offset - starts[low]
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function formatCheckResults(result, options = {}) {
|
|
153
|
+
const paint = options.color === false ? plain : ansi;
|
|
154
|
+
const output = [];
|
|
155
|
+
for (const checked of result.files) {
|
|
156
|
+
const starts = lineStarts(checked.source);
|
|
157
|
+
const lines = checked.source.split("\n");
|
|
158
|
+
for (const diagnostic of checked.diagnostics) {
|
|
159
|
+
const start = positionOf(starts, diagnostic.start);
|
|
160
|
+
const end = positionOf(starts, diagnostic.end);
|
|
161
|
+
output.push(`${paint.bold(checked.file)}${paint.dim(`:${start.line + 1}:${start.column + 1}`)} ${paint.red("error")} ${diagnostic.message}`);
|
|
162
|
+
const line = lines[start.line] ?? "";
|
|
163
|
+
const gutter = String(start.line + 1);
|
|
164
|
+
output.push(` ${paint.dim(`${gutter} \u2502`)} ${line}`);
|
|
165
|
+
const underlineLength = end.line === start.line ? Math.max(1, end.column - start.column) : Math.max(1, line.length - start.column);
|
|
166
|
+
output.push(` ${paint.dim(`${" ".repeat(gutter.length)} \u2502`)} ${" ".repeat(start.column)}${paint.red("^".repeat(underlineLength))}`);
|
|
167
|
+
output.push("");
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
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)`)}`;
|
|
171
|
+
output.push(summary);
|
|
172
|
+
return output.join("\n");
|
|
173
|
+
}
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all) __defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
17
|
+
get: () => from[key],
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
24
|
+
var check_exports = {};
|
|
25
|
+
__export(check_exports, {
|
|
26
|
+
MissingConfigArtifactError: () => MissingConfigArtifactError,
|
|
27
|
+
checkStyleFiles: () => checkStyleFiles,
|
|
28
|
+
createProjectExtractor: () => createProjectExtractor,
|
|
29
|
+
formatCheckResults: () => formatCheckResults
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(check_exports);
|
|
32
|
+
var import_fs = require("fs");
|
|
33
|
+
var import_path = require("path");
|
|
34
|
+
var import_parser = require("sucrase/dist/parser/index.js");
|
|
35
|
+
var import_types = require("sucrase/dist/parser/tokenizer/types.js");
|
|
36
|
+
var import_core = require("./core.native.js");
|
|
37
|
+
var import_document = require("./document.native.js");
|
|
38
|
+
var import_extract_sucrase = require("./extract-sucrase.native.js");
|
|
39
|
+
function _assert_this_initialized(self) {
|
|
40
|
+
if (self === void 0) {
|
|
41
|
+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
42
|
+
}
|
|
43
|
+
return self;
|
|
44
|
+
}
|
|
45
|
+
function _call_super(_this, derived, args) {
|
|
46
|
+
derived = _get_prototype_of(derived);
|
|
47
|
+
return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
|
|
48
|
+
}
|
|
49
|
+
function _class_call_check(instance, Constructor) {
|
|
50
|
+
if (!(instance instanceof Constructor)) {
|
|
51
|
+
throw new TypeError("Cannot call a class as a function");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function _construct(Parent, args, Class) {
|
|
55
|
+
if (_is_native_reflect_construct()) {
|
|
56
|
+
_construct = Reflect.construct;
|
|
57
|
+
} else {
|
|
58
|
+
_construct = function construct(Parent2, args2, Class2) {
|
|
59
|
+
var a = [null];
|
|
60
|
+
a.push.apply(a, args2);
|
|
61
|
+
var Constructor = Function.bind.apply(Parent2, a);
|
|
62
|
+
var instance = new Constructor();
|
|
63
|
+
if (Class2) _set_prototype_of(instance, Class2.prototype);
|
|
64
|
+
return instance;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return _construct.apply(null, arguments);
|
|
68
|
+
}
|
|
69
|
+
function _get_prototype_of(o) {
|
|
70
|
+
_get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o2) {
|
|
71
|
+
return o2.__proto__ || Object.getPrototypeOf(o2);
|
|
72
|
+
};
|
|
73
|
+
return _get_prototype_of(o);
|
|
74
|
+
}
|
|
75
|
+
function _inherits(subClass, superClass) {
|
|
76
|
+
if (typeof superClass !== "function" && superClass !== null) {
|
|
77
|
+
throw new TypeError("Super expression must either be null or a function");
|
|
78
|
+
}
|
|
79
|
+
subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: {
|
|
80
|
+
value: subClass,
|
|
81
|
+
writable: true,
|
|
82
|
+
configurable: true
|
|
83
|
+
} });
|
|
84
|
+
if (superClass) _set_prototype_of(subClass, superClass);
|
|
85
|
+
}
|
|
86
|
+
function _is_native_function(fn) {
|
|
87
|
+
return Function.toString.call(fn).indexOf("[native code]") !== -1;
|
|
88
|
+
}
|
|
89
|
+
function _possible_constructor_return(self, call) {
|
|
90
|
+
if (call && (_type_of(call) === "object" || typeof call === "function")) {
|
|
91
|
+
return call;
|
|
92
|
+
}
|
|
93
|
+
return _assert_this_initialized(self);
|
|
94
|
+
}
|
|
95
|
+
function _set_prototype_of(o, p) {
|
|
96
|
+
_set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o2, p2) {
|
|
97
|
+
o2.__proto__ = p2;
|
|
98
|
+
return o2;
|
|
99
|
+
};
|
|
100
|
+
return _set_prototype_of(o, p);
|
|
101
|
+
}
|
|
102
|
+
function _type_of(obj) {
|
|
103
|
+
"@swc/helpers - typeof";
|
|
104
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
105
|
+
}
|
|
106
|
+
function _wrap_native_super(Class) {
|
|
107
|
+
var _cache = typeof Map === "function" ? /* @__PURE__ */ new Map() : void 0;
|
|
108
|
+
_wrap_native_super = function wrapNativeSuper(Class2) {
|
|
109
|
+
if (Class2 === null || !_is_native_function(Class2)) return Class2;
|
|
110
|
+
if (typeof Class2 !== "function") {
|
|
111
|
+
throw new TypeError("Super expression must either be null or a function");
|
|
112
|
+
}
|
|
113
|
+
if (typeof _cache !== "undefined") {
|
|
114
|
+
if (_cache.has(Class2)) return _cache.get(Class2);
|
|
115
|
+
_cache.set(Class2, Wrapper);
|
|
116
|
+
}
|
|
117
|
+
function Wrapper() {
|
|
118
|
+
return _construct(Class2, arguments, _get_prototype_of(this).constructor);
|
|
119
|
+
}
|
|
120
|
+
Wrapper.prototype = Object.create(Class2.prototype, { constructor: {
|
|
121
|
+
value: Wrapper,
|
|
122
|
+
enumerable: false,
|
|
123
|
+
writable: true,
|
|
124
|
+
configurable: true
|
|
125
|
+
} });
|
|
126
|
+
return _set_prototype_of(Wrapper, Class2);
|
|
127
|
+
};
|
|
128
|
+
return _wrap_native_super(Class);
|
|
129
|
+
}
|
|
130
|
+
function _is_native_reflect_construct() {
|
|
131
|
+
try {
|
|
132
|
+
var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
|
|
133
|
+
} catch (_) {}
|
|
134
|
+
return (_is_native_reflect_construct = function() {
|
|
135
|
+
return !!result;
|
|
136
|
+
})();
|
|
137
|
+
}
|
|
138
|
+
var sourceExtensions = /\.(tsx|jsx)$/;
|
|
139
|
+
var skippedDirectories = /* @__PURE__ */ new Set([
|
|
140
|
+
"node_modules",
|
|
141
|
+
"dist",
|
|
142
|
+
"build",
|
|
143
|
+
"out",
|
|
144
|
+
"coverage",
|
|
145
|
+
".git",
|
|
146
|
+
".next",
|
|
147
|
+
".expo",
|
|
148
|
+
".tamagui"
|
|
149
|
+
]);
|
|
150
|
+
var MissingConfigArtifactError = /* @__PURE__ */ (function(Error1) {
|
|
151
|
+
"use strict";
|
|
152
|
+
_inherits(MissingConfigArtifactError2, Error1);
|
|
153
|
+
function MissingConfigArtifactError2(configPath) {
|
|
154
|
+
_class_call_check(this, MissingConfigArtifactError2);
|
|
155
|
+
var _this;
|
|
156
|
+
_this = _call_super(this, MissingConfigArtifactError2, [`no Tamagui config artifact at ${configPath} \u2014 run your dev server or \`tamagui generate\` once so the compiler emits it`]);
|
|
157
|
+
_this.name = "MissingConfigArtifactError";
|
|
158
|
+
return _this;
|
|
159
|
+
}
|
|
160
|
+
return MissingConfigArtifactError2;
|
|
161
|
+
})(_wrap_native_super(Error));
|
|
162
|
+
function walkSourceFiles(directory, results) {
|
|
163
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
164
|
+
try {
|
|
165
|
+
for (var _iterator = (0, import_fs.readdirSync)(directory, { withFileTypes: true })[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
166
|
+
var entry = _step.value;
|
|
167
|
+
if (entry.isDirectory()) {
|
|
168
|
+
if (!skippedDirectories.has(entry.name) && !entry.name.startsWith(".")) {
|
|
169
|
+
walkSourceFiles((0, import_path.join)(directory, entry.name), results);
|
|
170
|
+
}
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (sourceExtensions.test(entry.name)) results.push((0, import_path.join)(directory, entry.name));
|
|
174
|
+
}
|
|
175
|
+
} catch (err) {
|
|
176
|
+
_didIteratorError = true;
|
|
177
|
+
_iteratorError = err;
|
|
178
|
+
} finally {
|
|
179
|
+
try {
|
|
180
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
181
|
+
_iterator.return();
|
|
182
|
+
}
|
|
183
|
+
} finally {
|
|
184
|
+
if (_didIteratorError) {
|
|
185
|
+
throw _iteratorError;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function createProjectExtractor(isStyleProp) {
|
|
191
|
+
return (0, import_extract_sucrase.createSucraseStyleSiteExtractor)({
|
|
192
|
+
parse: import_parser.parse,
|
|
193
|
+
TokenType: import_types.TokenType
|
|
194
|
+
}, { isStyleProp });
|
|
195
|
+
}
|
|
196
|
+
function checkStyleFiles(options) {
|
|
197
|
+
var _options_configPath;
|
|
198
|
+
var configPath = (_options_configPath = options.configPath) !== null && _options_configPath !== void 0 ? _options_configPath : (0, import_path.join)(options.root, ".tamagui", "tamagui.config.json");
|
|
199
|
+
var contents;
|
|
200
|
+
try {
|
|
201
|
+
contents = (0, import_fs.readFileSync)(configPath, "utf8");
|
|
202
|
+
} catch (e) {
|
|
203
|
+
throw new MissingConfigArtifactError(configPath);
|
|
204
|
+
}
|
|
205
|
+
var tooling = (0, import_core.createStyleTooling)(JSON.parse(contents));
|
|
206
|
+
if (!tooling) throw new MissingConfigArtifactError(configPath);
|
|
207
|
+
var document = (0, import_document.createDocumentStyleTooling)(tooling, createProjectExtractor(function(name) {
|
|
208
|
+
return tooling.isStyleProp(name);
|
|
209
|
+
}));
|
|
210
|
+
var files;
|
|
211
|
+
if (options.files) {
|
|
212
|
+
files = [...options.files];
|
|
213
|
+
} else {
|
|
214
|
+
files = [];
|
|
215
|
+
walkSourceFiles(options.root, files);
|
|
216
|
+
files.sort();
|
|
217
|
+
}
|
|
218
|
+
var checked = [];
|
|
219
|
+
var diagnosticCount = 0;
|
|
220
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
221
|
+
try {
|
|
222
|
+
for (var _iterator = files[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
223
|
+
var file = _step.value;
|
|
224
|
+
var source = void 0;
|
|
225
|
+
try {
|
|
226
|
+
source = (0, import_fs.readFileSync)(file, "utf8");
|
|
227
|
+
} catch (e) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
var diagnostics = void 0;
|
|
231
|
+
try {
|
|
232
|
+
diagnostics = document.diagnostics(source);
|
|
233
|
+
} catch (e) {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
if (diagnostics.length === 0) continue;
|
|
237
|
+
diagnosticCount += diagnostics.length;
|
|
238
|
+
checked.push({
|
|
239
|
+
file: (0, import_path.relative)(options.root, file),
|
|
240
|
+
source,
|
|
241
|
+
diagnostics
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
} catch (err) {
|
|
245
|
+
_didIteratorError = true;
|
|
246
|
+
_iteratorError = err;
|
|
247
|
+
} finally {
|
|
248
|
+
try {
|
|
249
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
250
|
+
_iterator.return();
|
|
251
|
+
}
|
|
252
|
+
} finally {
|
|
253
|
+
if (_didIteratorError) {
|
|
254
|
+
throw _iteratorError;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
files: checked,
|
|
260
|
+
checkedFileCount: files.length,
|
|
261
|
+
diagnosticCount
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
var ansi = {
|
|
265
|
+
red: function(text) {
|
|
266
|
+
return `\x1B[31m${text}\x1B[39m`;
|
|
267
|
+
},
|
|
268
|
+
dim: function(text) {
|
|
269
|
+
return `\x1B[2m${text}\x1B[22m`;
|
|
270
|
+
},
|
|
271
|
+
bold: function(text) {
|
|
272
|
+
return `\x1B[1m${text}\x1B[22m`;
|
|
273
|
+
},
|
|
274
|
+
cyan: function(text) {
|
|
275
|
+
return `\x1B[36m${text}\x1B[39m`;
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
var plain = {
|
|
279
|
+
red: function(text) {
|
|
280
|
+
return text;
|
|
281
|
+
},
|
|
282
|
+
dim: function(text) {
|
|
283
|
+
return text;
|
|
284
|
+
},
|
|
285
|
+
bold: function(text) {
|
|
286
|
+
return text;
|
|
287
|
+
},
|
|
288
|
+
cyan: function(text) {
|
|
289
|
+
return text;
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
function lineStarts(source) {
|
|
293
|
+
var starts = [0];
|
|
294
|
+
for (var index = 0; index < source.length; index++) {
|
|
295
|
+
if (source.charCodeAt(index) === 10) starts.push(index + 1);
|
|
296
|
+
}
|
|
297
|
+
return starts;
|
|
298
|
+
}
|
|
299
|
+
function positionOf(starts, offset) {
|
|
300
|
+
var low = 0;
|
|
301
|
+
var high = starts.length - 1;
|
|
302
|
+
while (low < high) {
|
|
303
|
+
var mid = low + high + 1 >> 1;
|
|
304
|
+
if (starts[mid] <= offset) low = mid;
|
|
305
|
+
else high = mid - 1;
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
line: low,
|
|
309
|
+
column: offset - starts[low]
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function formatCheckResults(result) {
|
|
313
|
+
var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
314
|
+
var paint = options.color === false ? plain : ansi;
|
|
315
|
+
var output = [];
|
|
316
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
317
|
+
try {
|
|
318
|
+
for (var _iterator = result.files[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
319
|
+
var checked = _step.value;
|
|
320
|
+
var starts = lineStarts(checked.source);
|
|
321
|
+
var lines = checked.source.split("\n");
|
|
322
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = void 0;
|
|
323
|
+
try {
|
|
324
|
+
for (var _iterator1 = checked.diagnostics[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
|
|
325
|
+
var diagnostic = _step1.value;
|
|
326
|
+
var start = positionOf(starts, diagnostic.start);
|
|
327
|
+
var end = positionOf(starts, diagnostic.end);
|
|
328
|
+
output.push(`${paint.bold(checked.file)}${paint.dim(`:${start.line + 1}:${start.column + 1}`)} ${paint.red("error")} ${diagnostic.message}`);
|
|
329
|
+
var _lines_start_line;
|
|
330
|
+
var line = (_lines_start_line = lines[start.line]) !== null && _lines_start_line !== void 0 ? _lines_start_line : "";
|
|
331
|
+
var gutter = String(start.line + 1);
|
|
332
|
+
output.push(` ${paint.dim(`${gutter} \u2502`)} ${line}`);
|
|
333
|
+
var underlineLength = end.line === start.line ? Math.max(1, end.column - start.column) : Math.max(1, line.length - start.column);
|
|
334
|
+
output.push(` ${paint.dim(`${" ".repeat(gutter.length)} \u2502`)} ${" ".repeat(start.column)}${paint.red("^".repeat(underlineLength))}`);
|
|
335
|
+
output.push("");
|
|
336
|
+
}
|
|
337
|
+
} catch (err) {
|
|
338
|
+
_didIteratorError1 = true;
|
|
339
|
+
_iteratorError1 = err;
|
|
340
|
+
} finally {
|
|
341
|
+
try {
|
|
342
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
343
|
+
_iterator1.return();
|
|
344
|
+
}
|
|
345
|
+
} finally {
|
|
346
|
+
if (_didIteratorError1) {
|
|
347
|
+
throw _iteratorError1;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
} catch (err) {
|
|
353
|
+
_didIteratorError = true;
|
|
354
|
+
_iteratorError = err;
|
|
355
|
+
} finally {
|
|
356
|
+
try {
|
|
357
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
358
|
+
_iterator.return();
|
|
359
|
+
}
|
|
360
|
+
} finally {
|
|
361
|
+
if (_didIteratorError) {
|
|
362
|
+
throw _iteratorError;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
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)`)}`;
|
|
367
|
+
output.push(summary);
|
|
368
|
+
return output.join("\n");
|
|
369
|
+
}
|