@pikacss/integration 0.0.46 → 0.0.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +16 -12
- package/dist/index.mjs +122 -50
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -3,7 +3,7 @@ import { SourceMap } from "magic-string";
|
|
|
3
3
|
export * from "@pikacss/core";
|
|
4
4
|
|
|
5
5
|
//#region src/eventHook.d.ts
|
|
6
|
-
type EventHookListener<EventPayload> = (payload: EventPayload) => void
|
|
6
|
+
type EventHookListener<EventPayload> = (payload: EventPayload) => void;
|
|
7
7
|
interface EventHook<EventPayload> {
|
|
8
8
|
listeners: Set<EventHookListener<EventPayload>>;
|
|
9
9
|
trigger: (payload: EventPayload) => void;
|
|
@@ -38,6 +38,19 @@ interface IntegrationContextOptions {
|
|
|
38
38
|
cssCodegen: string;
|
|
39
39
|
autoCreateConfig: boolean;
|
|
40
40
|
}
|
|
41
|
+
type LoadedConfigResult = {
|
|
42
|
+
config: EngineConfig;
|
|
43
|
+
file: null;
|
|
44
|
+
content: null;
|
|
45
|
+
} | {
|
|
46
|
+
config: null;
|
|
47
|
+
file: null;
|
|
48
|
+
content: null;
|
|
49
|
+
} | {
|
|
50
|
+
config: EngineConfig;
|
|
51
|
+
file: string;
|
|
52
|
+
content: string;
|
|
53
|
+
};
|
|
41
54
|
interface IntegrationContext {
|
|
42
55
|
cwd: string;
|
|
43
56
|
currentPackageName: string;
|
|
@@ -49,16 +62,7 @@ interface IntegrationContext {
|
|
|
49
62
|
resolvedConfig: EngineConfig | Nullish;
|
|
50
63
|
resolvedConfigPath: string | Nullish;
|
|
51
64
|
resolvedConfigContent: string | Nullish;
|
|
52
|
-
loadConfig: () => Promise<
|
|
53
|
-
config: EngineConfig;
|
|
54
|
-
file: null;
|
|
55
|
-
} | {
|
|
56
|
-
config: null;
|
|
57
|
-
file: null;
|
|
58
|
-
} | {
|
|
59
|
-
config: EngineConfig;
|
|
60
|
-
file: string;
|
|
61
|
-
}>;
|
|
65
|
+
loadConfig: () => Promise<LoadedConfigResult>;
|
|
62
66
|
usages: Map<string, UsageRecord[]>;
|
|
63
67
|
hooks: {
|
|
64
68
|
styleUpdated: ReturnType<typeof createEventHook<void>>;
|
|
@@ -85,4 +89,4 @@ interface IntegrationContext {
|
|
|
85
89
|
//#region src/ctx.d.ts
|
|
86
90
|
declare function createCtx(options: IntegrationContextOptions): IntegrationContext;
|
|
87
91
|
//#endregion
|
|
88
|
-
export { FnUtils, IntegrationContext, IntegrationContextOptions, UsageRecord, createCtx };
|
|
92
|
+
export { FnUtils, IntegrationContext, IntegrationContextOptions, LoadedConfigResult, UsageRecord, createCtx };
|
package/dist/index.mjs
CHANGED
|
@@ -35,21 +35,37 @@ function createEventHook() {
|
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/tsCodegen.ts
|
|
38
|
+
function formatUnionType(parts) {
|
|
39
|
+
return parts.length > 0 ? parts.join(" | ") : "never";
|
|
40
|
+
}
|
|
38
41
|
function formatUnionStringType(list) {
|
|
39
|
-
return list.
|
|
42
|
+
return formatUnionType(list.map((i) => JSON.stringify(i)));
|
|
43
|
+
}
|
|
44
|
+
function formatAutocompleteUnion(literals, patterns) {
|
|
45
|
+
return formatUnionType([...Array.from(literals, (value) => JSON.stringify(value)), ...patterns == null ? [] : [...patterns]]);
|
|
46
|
+
}
|
|
47
|
+
function formatAutocompleteValueMap(keys, entries, patternEntries, formatValue) {
|
|
48
|
+
const mergedKeys = new Set(keys);
|
|
49
|
+
for (const key of entries.keys()) mergedKeys.add(key);
|
|
50
|
+
for (const key of patternEntries.keys()) mergedKeys.add(key);
|
|
51
|
+
return mergedKeys.size > 0 ? `{ ${Array.from(mergedKeys, (key) => `${JSON.stringify(key)}: ${formatValue(entries.get(key) || [], patternEntries.get(key) || [])}`).join(", ")} }` : "never";
|
|
40
52
|
}
|
|
41
53
|
function generateAutocomplete(ctx) {
|
|
42
54
|
const autocomplete = ctx.engine.config.autocomplete;
|
|
55
|
+
const patterns = autocomplete.patterns ?? {
|
|
56
|
+
selectors: /* @__PURE__ */ new Set(),
|
|
57
|
+
styleItemStrings: /* @__PURE__ */ new Set(),
|
|
58
|
+
properties: /* @__PURE__ */ new Map(),
|
|
59
|
+
cssProperties: /* @__PURE__ */ new Map()
|
|
60
|
+
};
|
|
43
61
|
const { layers } = ctx.engine.config;
|
|
44
62
|
const layerNames = sortLayerNames(layers);
|
|
45
63
|
return [
|
|
46
64
|
"export type Autocomplete = DefineAutocomplete<{",
|
|
47
|
-
` Selector: ${
|
|
48
|
-
` StyleItemString: ${
|
|
49
|
-
`
|
|
50
|
-
`
|
|
51
|
-
` PropertiesValue: { ${Array.from(autocomplete.properties.entries(), ([k, v]) => `${JSON.stringify(k)}: ${v.length > 0 ? v.join(" | ") : "never"}`).join(", ")} }`,
|
|
52
|
-
` CssPropertiesValue: { ${Array.from(autocomplete.cssProperties.entries(), ([k, v]) => `${JSON.stringify(k)}: ${formatUnionStringType(v)}`).join(", ")} }`,
|
|
65
|
+
` Selector: ${formatAutocompleteUnion(autocomplete.selectors, patterns.selectors)}`,
|
|
66
|
+
` StyleItemString: ${formatAutocompleteUnion(autocomplete.styleItemStrings, patterns.styleItemStrings)}`,
|
|
67
|
+
` PropertyValue: ${formatAutocompleteValueMap(autocomplete.extraProperties, autocomplete.properties, patterns.properties, (values, patterns) => formatUnionType([...values, ...patterns]))}`,
|
|
68
|
+
` CSSPropertyValue: ${formatAutocompleteValueMap(autocomplete.extraCssProperties, autocomplete.cssProperties, patterns.cssProperties, (values, patterns) => formatAutocompleteUnion(values, patterns))}`,
|
|
53
69
|
` Layer: ${formatUnionStringType(layerNames)}`,
|
|
54
70
|
"}>",
|
|
55
71
|
""
|
|
@@ -148,7 +164,7 @@ async function generateTsCodegenContent(ctx) {
|
|
|
148
164
|
" interface PikaAugment {",
|
|
149
165
|
" Autocomplete: Autocomplete",
|
|
150
166
|
" Selector: Autocomplete['Selector'] | CSSSelector",
|
|
151
|
-
" CSSProperty: Autocomplete['
|
|
167
|
+
" CSSProperty: ([Autocomplete['CSSPropertyValue']] extends [never] ? never : Extract<keyof Autocomplete['CSSPropertyValue'], string>) | CSSProperty",
|
|
152
168
|
" Properties: Properties",
|
|
153
169
|
" StyleDefinition: StyleDefinition",
|
|
154
170
|
" StyleItem: StyleItem",
|
|
@@ -167,6 +183,36 @@ async function generateTsCodegenContent(ctx) {
|
|
|
167
183
|
|
|
168
184
|
//#endregion
|
|
169
185
|
//#region src/ctx.ts
|
|
186
|
+
function createConfigScaffoldContent({ currentPackageName, resolvedConfigPath, tsCodegenFilepath }) {
|
|
187
|
+
const relativeTsCodegenFilepath = tsCodegenFilepath == null ? null : `./${relative(dirname(resolvedConfigPath), tsCodegenFilepath)}`;
|
|
188
|
+
return [
|
|
189
|
+
...relativeTsCodegenFilepath == null ? [] : [`/// <reference path="${relativeTsCodegenFilepath}" />`],
|
|
190
|
+
`import { defineEngineConfig } from '${currentPackageName}'`,
|
|
191
|
+
"",
|
|
192
|
+
"export default defineEngineConfig({",
|
|
193
|
+
" // Add your PikaCSS engine config here",
|
|
194
|
+
"})"
|
|
195
|
+
].join("\n");
|
|
196
|
+
}
|
|
197
|
+
async function writeGeneratedFile(filepath, content) {
|
|
198
|
+
await mkdir(dirname(filepath), { recursive: true }).catch(() => {});
|
|
199
|
+
await writeFile(filepath, content);
|
|
200
|
+
}
|
|
201
|
+
async function evaluateConfigModule(resolvedConfigPath) {
|
|
202
|
+
log.info(`Using config file: ${resolvedConfigPath}`);
|
|
203
|
+
const { createJiti } = await import("jiti");
|
|
204
|
+
const jiti = createJiti(import.meta.url, { interopDefault: true });
|
|
205
|
+
const content = await readFile(resolvedConfigPath, "utf-8");
|
|
206
|
+
const config = (await jiti.evalModule(content, {
|
|
207
|
+
id: resolvedConfigPath,
|
|
208
|
+
forceTranspile: true
|
|
209
|
+
})).default;
|
|
210
|
+
return {
|
|
211
|
+
config: klona(config),
|
|
212
|
+
file: resolvedConfigPath,
|
|
213
|
+
content
|
|
214
|
+
};
|
|
215
|
+
}
|
|
170
216
|
function usePaths({ cwd: _cwd, cssCodegen, tsCodegen }) {
|
|
171
217
|
const cwd = signal(_cwd);
|
|
172
218
|
return {
|
|
@@ -189,6 +235,20 @@ function useConfig({ cwd, tsCodegenFilepath, currentPackageName, autoCreateConfi
|
|
|
189
235
|
for await (const entry of stream) return join(_cwd, entry);
|
|
190
236
|
return null;
|
|
191
237
|
}
|
|
238
|
+
async function ensureConfigPath(candidatePath) {
|
|
239
|
+
if (candidatePath != null) return candidatePath;
|
|
240
|
+
if (autoCreateConfig === false) {
|
|
241
|
+
log.warn("Config file not found and autoCreateConfig is false");
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
const resolvedConfigPath = specificConfigPath() ?? join(cwd(), "pika.config.js");
|
|
245
|
+
await writeGeneratedFile(resolvedConfigPath, createConfigScaffoldContent({
|
|
246
|
+
currentPackageName,
|
|
247
|
+
resolvedConfigPath,
|
|
248
|
+
tsCodegenFilepath: tsCodegenFilepath()
|
|
249
|
+
}));
|
|
250
|
+
return resolvedConfigPath;
|
|
251
|
+
}
|
|
192
252
|
const inlineConfig = typeof configOrPath === "object" ? configOrPath : null;
|
|
193
253
|
async function _loadConfig() {
|
|
194
254
|
try {
|
|
@@ -201,43 +261,13 @@ function useConfig({ cwd, tsCodegenFilepath, currentPackageName, autoCreateConfi
|
|
|
201
261
|
content: null
|
|
202
262
|
};
|
|
203
263
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return {
|
|
210
|
-
config: null,
|
|
211
|
-
file: null,
|
|
212
|
-
content: null
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
resolvedConfigPath = join(_cwd, specificConfigPath() ?? "pika.config.js");
|
|
216
|
-
await mkdir(dirname(resolvedConfigPath), { recursive: true }).catch(() => {});
|
|
217
|
-
const _tsCodegenFilepath = tsCodegenFilepath();
|
|
218
|
-
const relativeTsCodegenFilepath = _tsCodegenFilepath == null ? null : `./${relative(dirname(resolvedConfigPath), _tsCodegenFilepath)}`;
|
|
219
|
-
await writeFile(resolvedConfigPath, [
|
|
220
|
-
...relativeTsCodegenFilepath == null ? [] : [`/// <reference path="${relativeTsCodegenFilepath}" />`],
|
|
221
|
-
`import { defineEngineConfig } from '${currentPackageName}'`,
|
|
222
|
-
"",
|
|
223
|
-
"export default defineEngineConfig({",
|
|
224
|
-
" // Add your PikaCSS engine config here",
|
|
225
|
-
"})"
|
|
226
|
-
].join("\n"));
|
|
227
|
-
}
|
|
228
|
-
log.info(`Using config file: ${resolvedConfigPath}`);
|
|
229
|
-
const { createJiti } = await import("jiti");
|
|
230
|
-
const jiti = createJiti(import.meta.url, { interopDefault: true });
|
|
231
|
-
const content = await readFile(resolvedConfigPath, "utf-8");
|
|
232
|
-
const config = (await jiti.evalModule(content, {
|
|
233
|
-
id: resolvedConfigPath,
|
|
234
|
-
forceTranspile: true
|
|
235
|
-
})).default;
|
|
236
|
-
return {
|
|
237
|
-
config: klona(config),
|
|
238
|
-
file: resolvedConfigPath,
|
|
239
|
-
content
|
|
264
|
+
const resolvedConfigPath = await ensureConfigPath(await findFirstExistingConfigPath());
|
|
265
|
+
if (resolvedConfigPath == null) return {
|
|
266
|
+
config: null,
|
|
267
|
+
file: null,
|
|
268
|
+
content: null
|
|
240
269
|
};
|
|
270
|
+
return await evaluateConfigModule(resolvedConfigPath);
|
|
241
271
|
} catch (error) {
|
|
242
272
|
log.error(`Failed to load config file: ${error.message}`, error);
|
|
243
273
|
return {
|
|
@@ -304,6 +334,46 @@ function useTransform({ cwd, cssCodegenFilepath, tsCodegenFilepath, scan, fnName
|
|
|
304
334
|
};
|
|
305
335
|
}
|
|
306
336
|
const fnUtils = createFnUtils(fnName);
|
|
337
|
+
function findTemplateExpressionEnd(code, start) {
|
|
338
|
+
let end = start;
|
|
339
|
+
let depth = 1;
|
|
340
|
+
let inString = false;
|
|
341
|
+
let isEscaped = false;
|
|
342
|
+
while (depth > 0 && end < code.length - 1) {
|
|
343
|
+
end++;
|
|
344
|
+
const char = code[end];
|
|
345
|
+
if (isEscaped) {
|
|
346
|
+
isEscaped = false;
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
if (char === "\\") {
|
|
350
|
+
isEscaped = true;
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
if (inString !== false) {
|
|
354
|
+
if (char === inString) inString = false;
|
|
355
|
+
else if (inString === "`" && char === "$" && code[end + 1] === "{") {
|
|
356
|
+
const nestedExpressionEnd = findTemplateExpressionEnd(code, end + 1);
|
|
357
|
+
if (nestedExpressionEnd === -1) return -1;
|
|
358
|
+
end = nestedExpressionEnd;
|
|
359
|
+
}
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
if (char === "{") depth++;
|
|
363
|
+
else if (char === "}") depth--;
|
|
364
|
+
else if (char === "'" || char === "\"" || char === "`") inString = char;
|
|
365
|
+
else if (char === "/" && code[end + 1] === "/") {
|
|
366
|
+
const lineEnd = code.indexOf("\n", end);
|
|
367
|
+
if (lineEnd === -1) return -1;
|
|
368
|
+
end = lineEnd;
|
|
369
|
+
} else if (char === "/" && code[end + 1] === "*") {
|
|
370
|
+
const commentEnd = code.indexOf("*/", end + 2);
|
|
371
|
+
if (commentEnd === -1) return -1;
|
|
372
|
+
end = commentEnd + 1;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return depth === 0 ? end : -1;
|
|
376
|
+
}
|
|
307
377
|
function findFunctionCalls(code) {
|
|
308
378
|
const RE = fnUtils.RE;
|
|
309
379
|
const result = [];
|
|
@@ -329,8 +399,12 @@ function useTransform({ cwd, cssCodegenFilepath, tsCodegenFilepath, scan, fnName
|
|
|
329
399
|
if (inString !== false) {
|
|
330
400
|
if (char === inString) inString = false;
|
|
331
401
|
else if (inString === "`" && char === "$" && code[end + 1] === "{") {
|
|
332
|
-
end
|
|
333
|
-
|
|
402
|
+
const templateExpressionEnd = findTemplateExpressionEnd(code, end + 1);
|
|
403
|
+
if (templateExpressionEnd === -1) {
|
|
404
|
+
log.warn(`Malformed template literal expression in function call at position ${start}`);
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
end = templateExpressionEnd;
|
|
334
408
|
}
|
|
335
409
|
continue;
|
|
336
410
|
}
|
|
@@ -509,18 +583,16 @@ function createCtx(options) {
|
|
|
509
583
|
await ctx.setupPromise;
|
|
510
584
|
const content = await ctx.getCssCodegenContent();
|
|
511
585
|
if (content == null) return;
|
|
512
|
-
await mkdir(dirname(ctx.cssCodegenFilepath), { recursive: true }).catch(() => {});
|
|
513
586
|
log.debug(`Writing CSS code generation file: ${ctx.cssCodegenFilepath}`);
|
|
514
|
-
await
|
|
587
|
+
await writeGeneratedFile(ctx.cssCodegenFilepath, content);
|
|
515
588
|
},
|
|
516
589
|
writeTsCodegenFile: async () => {
|
|
517
590
|
await ctx.setupPromise;
|
|
518
591
|
if (ctx.tsCodegenFilepath == null) return;
|
|
519
592
|
const content = await ctx.getTsCodegenContent();
|
|
520
593
|
if (content == null) return;
|
|
521
|
-
await mkdir(dirname(ctx.tsCodegenFilepath), { recursive: true }).catch(() => {});
|
|
522
594
|
log.debug(`Writing TypeScript code generation file: ${ctx.tsCodegenFilepath}`);
|
|
523
|
-
await
|
|
595
|
+
await writeGeneratedFile(ctx.tsCodegenFilepath, content);
|
|
524
596
|
},
|
|
525
597
|
fullyCssCodegen: async () => {
|
|
526
598
|
await ctx.setupPromise;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikacss/integration",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.47",
|
|
5
5
|
"author": "DevilTea <ch19980814@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"micromatch": "^4.0.8",
|
|
45
45
|
"pathe": "^2.0.3",
|
|
46
46
|
"perfect-debounce": "^2.1.0",
|
|
47
|
-
"@pikacss/core": "0.0.
|
|
47
|
+
"@pikacss/core": "0.0.47"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/micromatch": "^4.0.10"
|