@pikacss/integration 0.0.30 → 0.0.31

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.mjs CHANGED
@@ -1,414 +1,418 @@
1
- import { statSync } from 'node:fs';
2
- import { writeFile, mkdir, readFile } from 'node:fs/promises';
3
- import { setWarnFn, warn, defineEnginePlugin, createEngine } from '@pikacss/core';
4
- export * from '@pikacss/core';
5
- import { createJiti } from 'jiti';
6
- import { klona } from 'klona';
7
- import { isPackageExists } from 'local-pkg';
8
- import MagicString from 'magic-string';
9
- import micromatch from 'micromatch';
10
- import { isAbsolute, resolve, join, dirname, relative } from 'pathe';
11
- import { debounce } from 'perfect-debounce';
1
+ import { statSync } from "node:fs";
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { createEngine, defineEnginePlugin, setWarnFn, warn } from "@pikacss/core";
4
+ import { createJiti } from "jiti";
5
+ import { klona } from "klona";
6
+ import { isPackageExists } from "local-pkg";
7
+ import MagicString from "magic-string";
8
+ import micromatch from "micromatch";
9
+ import { dirname, isAbsolute, join, relative, resolve } from "pathe";
10
+ import { debounce } from "perfect-debounce";
12
11
 
12
+ export * from "@pikacss/core"
13
+
14
+ //#region src/eventHook.ts
13
15
  function createEventHook() {
14
- const listeners = /* @__PURE__ */ new Set();
15
- function trigger(payload) {
16
- listeners.forEach((listener) => listener(payload));
17
- }
18
- function off(listener) {
19
- listeners.delete(listener);
20
- }
21
- function on(listener) {
22
- listeners.add(listener);
23
- const offListener = () => off(listener);
24
- return offListener;
25
- }
26
- return {
27
- listeners,
28
- trigger,
29
- on,
30
- off
31
- };
16
+ const listeners = /* @__PURE__ */ new Set();
17
+ function trigger(payload) {
18
+ listeners.forEach((listener) => listener(payload));
19
+ }
20
+ function off(listener) {
21
+ listeners.delete(listener);
22
+ }
23
+ function on(listener) {
24
+ listeners.add(listener);
25
+ const offListener = () => off(listener);
26
+ return offListener;
27
+ }
28
+ return {
29
+ listeners,
30
+ trigger,
31
+ on,
32
+ off
33
+ };
32
34
  }
33
35
 
36
+ //#endregion
37
+ //#region src/tsCodegen.ts
34
38
  function formatUnionStringType(list) {
35
- return list.length > 0 ? list.map((i) => typeof i === "number" ? i : `'${i}'`).join(" | ") : "never";
39
+ return list.length > 0 ? list.map((i) => typeof i === "number" ? i : `'${i}'`).join(" | ") : "never";
36
40
  }
37
41
  function generateAutocomplete(ctx) {
38
- const autocomplete = ctx.engine.config.autocomplete;
39
- return [
40
- "export type Autocomplete = DefineAutocomplete<{",
41
- ` Selector: ${formatUnionStringType([...autocomplete.selectors])}`,
42
- ` StyleItemString: ${formatUnionStringType([...autocomplete.styleItemStrings])}`,
43
- ` ExtraProperty: ${formatUnionStringType([...autocomplete.extraProperties])}`,
44
- ` ExtraCssProperty: ${formatUnionStringType([...autocomplete.extraCssProperties])}`,
45
- ` PropertiesValue: { ${Array.from(autocomplete.properties.entries(), ([k, v]) => `'${k}': ${v.join(" | ")}`).join(",")} }`,
46
- ` CssPropertiesValue: { ${Array.from(autocomplete.cssProperties.entries(), ([k, v]) => `'${k}': ${formatUnionStringType(v)}`).join(",")} }`,
47
- "}>",
48
- ""
49
- ];
42
+ const autocomplete = ctx.engine.config.autocomplete;
43
+ return [
44
+ "export type Autocomplete = DefineAutocomplete<{",
45
+ ` Selector: ${formatUnionStringType([...autocomplete.selectors])}`,
46
+ ` StyleItemString: ${formatUnionStringType([...autocomplete.styleItemStrings])}`,
47
+ ` ExtraProperty: ${formatUnionStringType([...autocomplete.extraProperties])}`,
48
+ ` ExtraCssProperty: ${formatUnionStringType([...autocomplete.extraCssProperties])}`,
49
+ ` PropertiesValue: { ${Array.from(autocomplete.properties.entries(), ([k, v]) => `'${k}': ${v.join(" | ")}`).join(",")} }`,
50
+ ` CssPropertiesValue: { ${Array.from(autocomplete.cssProperties.entries(), ([k, v]) => `'${k}': ${formatUnionStringType(v)}`).join(",")} }`,
51
+ "}>",
52
+ ""
53
+ ];
50
54
  }
51
55
  function generateStyleFn(ctx) {
52
- const { transformedFormat } = ctx;
53
- const lines = [
54
- "type StyleFn_Array = (...params: StyleItem[]) => string[]",
55
- "type StyleFn_String = (...params: StyleItem[]) => string",
56
- "type StyleFn_Inline = (...params: StyleItem[]) => void"
57
- ];
58
- if (transformedFormat === "array")
59
- lines.push("type StyleFn_Normal = StyleFn_Array");
60
- else if (transformedFormat === "string")
61
- lines.push("type StyleFn_Normal = StyleFn_String");
62
- else if (transformedFormat === "inline")
63
- lines.push("type StyleFn_Normal = StyleFn_Inline");
64
- lines.push(
65
- "type StyleFn = StyleFn_Normal & {",
66
- " str: StyleFn_String",
67
- " arr: StyleFn_Array",
68
- " inl: StyleFn_Inline",
69
- "}",
70
- `type StyleFnWithPreview = PreviewOverloads<StyleFn_Normal>['fn'] & {`,
71
- ` str: PreviewOverloads<StyleFn_String>['fn']`,
72
- ` arr: PreviewOverloads<StyleFn_Array>['fn']`,
73
- ` inl: PreviewOverloads<StyleFn_Inline>['fn']`,
74
- "}",
75
- ""
76
- );
77
- return lines;
56
+ const { transformedFormat } = ctx;
57
+ const lines = [
58
+ "type StyleFn_Array = (...params: StyleItem[]) => string[]",
59
+ "type StyleFn_String = (...params: StyleItem[]) => string",
60
+ "type StyleFn_Inline = (...params: StyleItem[]) => void"
61
+ ];
62
+ if (transformedFormat === "array") lines.push("type StyleFn_Normal = StyleFn_Array");
63
+ else if (transformedFormat === "string") lines.push("type StyleFn_Normal = StyleFn_String");
64
+ else if (transformedFormat === "inline") lines.push("type StyleFn_Normal = StyleFn_Inline");
65
+ lines.push("type StyleFn = StyleFn_Normal & {", " str: StyleFn_String", " arr: StyleFn_Array", " inl: StyleFn_Inline", "}", `type StyleFnWithPreview = PreviewOverloads<StyleFn_Normal>[\'fn\'] & {`, ` str: PreviewOverloads<StyleFn_String>[\'fn\']`, ` arr: PreviewOverloads<StyleFn_Array>[\'fn\']`, ` inl: PreviewOverloads<StyleFn_Inline>[\'fn\']`, "}", "");
66
+ return lines;
78
67
  }
79
68
  function generateGlobalDeclaration(ctx) {
80
- const { fnName } = ctx;
81
- return [
82
- "declare global {",
83
- " /**",
84
- " * PikaCSS",
85
- " */",
86
- ` const ${fnName}: StyleFn`,
87
- "",
88
- " /**",
89
- " * PikaCSS Preview",
90
- " */",
91
- ` const ${fnName}p: StyleFnWithPreview`,
92
- "}",
93
- ""
94
- ];
69
+ const { fnName } = ctx;
70
+ return [
71
+ "declare global {",
72
+ " /**",
73
+ " * PikaCSS",
74
+ " */",
75
+ ` const ${fnName}: StyleFn`,
76
+ "",
77
+ " /**",
78
+ " * PikaCSS Preview",
79
+ " */",
80
+ ` const ${fnName}p: StyleFnWithPreview`,
81
+ "}",
82
+ ""
83
+ ];
95
84
  }
96
85
  function generateVueDeclaration(ctx) {
97
- const { hasVue, fnName } = ctx;
98
- if (!hasVue)
99
- return [];
100
- return [
101
- "declare module 'vue' {",
102
- " interface ComponentCustomProperties {",
103
- " /**",
104
- " * PikaCSS",
105
- " */",
106
- ` ${fnName}: StyleFn`,
107
- "",
108
- " /**",
109
- " * PikaCSS Preview",
110
- " */",
111
- ` ${fnName}p: StyleFnWithPreview`,
112
- " }",
113
- "}",
114
- ""
115
- ];
86
+ const { hasVue, fnName } = ctx;
87
+ if (!hasVue) return [];
88
+ return [
89
+ "declare module 'vue' {",
90
+ " interface ComponentCustomProperties {",
91
+ " /**",
92
+ " * PikaCSS",
93
+ " */",
94
+ ` ${fnName}: StyleFn`,
95
+ "",
96
+ " /**",
97
+ " * PikaCSS Preview",
98
+ " */",
99
+ ` ${fnName}p: StyleFnWithPreview`,
100
+ " }",
101
+ "}",
102
+ ""
103
+ ];
116
104
  }
117
105
  async function generateOverloadContent(ctx) {
118
- const paramsLines = [];
119
- const fnsLines = [];
120
- const usages = [...ctx.usages.values()].flat();
121
- for (let i = 0; i < usages.length; i++) {
122
- const usage = usages[i];
123
- try {
124
- const addedParamsLines = usage.params.map((param, index) => `type P${i}_${index} = ${JSON.stringify(param)}`);
125
- const addedFnLines = [
126
- " /**",
127
- " * ### PikaCSS Preview",
128
- " * ```css",
129
- // CSS Lines
130
- ...(await ctx.engine.renderAtomicStyles(true, { atomicStyleIds: usage.atomicStyleIds, isPreview: true })).trim().split("\n").map((line) => ` * \u200E${line.replace(/^(\s*)/, "$1\u200E")}`),
131
- " * ```",
132
- " */",
133
- ` fn(...params: [${usage.params.map((_, index) => `p${index}: P${i}_${index}`).join(", ")}]): ReturnType<StyleFn>`
134
- ];
135
- paramsLines.push(...addedParamsLines);
136
- fnsLines.push(...addedFnLines);
137
- } catch {
138
- }
139
- }
140
- return [
141
- "interface PreviewOverloads<StyleFn extends (StyleFn_Array | StyleFn_String | StyleFn_Inline)> {",
142
- ...fnsLines,
143
- " /**",
144
- " * PikaCSS Preview",
145
- " * Save the current file to see the preview.",
146
- " */",
147
- ` fn(...params: Parameters<StyleFn>): ReturnType<StyleFn>`,
148
- "}",
149
- ...paramsLines
150
- ];
106
+ const paramsLines = [];
107
+ const fnsLines = [];
108
+ const usages = [...ctx.usages.values()].flat();
109
+ for (let i = 0; i < usages.length; i++) {
110
+ const usage = usages[i];
111
+ try {
112
+ const addedParamsLines = usage.params.map((param, index) => `type P${i}_${index} = ${JSON.stringify(param)}`);
113
+ const addedFnLines = [
114
+ " /**",
115
+ " * ### PikaCSS Preview",
116
+ " * ```css",
117
+ ...(await ctx.engine.renderAtomicStyles(true, {
118
+ atomicStyleIds: usage.atomicStyleIds,
119
+ isPreview: true
120
+ })).trim().split("\n").map((line) => ` * ‎${line.replace(/^(\s*)/, "$1‎")}`),
121
+ " * ```",
122
+ " */",
123
+ ` fn(...params: [${usage.params.map((_, index) => `p${index}: P${i}_${index}`).join(", ")}]): ReturnType<StyleFn>`
124
+ ];
125
+ paramsLines.push(...addedParamsLines);
126
+ fnsLines.push(...addedFnLines);
127
+ } catch {}
128
+ }
129
+ return [
130
+ "interface PreviewOverloads<StyleFn extends (StyleFn_Array | StyleFn_String | StyleFn_Inline)> {",
131
+ ...fnsLines,
132
+ " /**",
133
+ " * PikaCSS Preview",
134
+ " * Save the current file to see the preview.",
135
+ " */",
136
+ ` fn(...params: Parameters<StyleFn>): ReturnType<StyleFn>`,
137
+ "}",
138
+ ...paramsLines
139
+ ];
151
140
  }
152
141
  async function generateTsCodegenContent(ctx) {
153
- const lines = [
154
- `// Auto-generated by ${ctx.currentPackageName}`,
155
- `import type { CSSProperty, CSSSelectors, DefineAutocomplete, Properties, StyleDefinition, StyleItem } from '${ctx.currentPackageName}'`,
156
- "",
157
- `declare module '${ctx.currentPackageName}' {`,
158
- " interface PikaAugment {",
159
- " Autocomplete: Autocomplete",
160
- " Selector: Autocomplete['Selector'] | CSSSelectors",
161
- " CSSProperty: Autocomplete['ExtraCssProperty'] | CSSProperty",
162
- " Properties: Properties",
163
- " StyleDefinition: StyleDefinition",
164
- " StyleItem: StyleItem",
165
- " }",
166
- "}",
167
- ""
168
- ];
169
- lines.push(...generateAutocomplete(ctx));
170
- lines.push(...generateStyleFn(ctx));
171
- lines.push(...generateGlobalDeclaration(ctx));
172
- lines.push(...generateVueDeclaration(ctx));
173
- lines.push(...await generateOverloadContent(ctx));
174
- return lines.join("\n");
142
+ const lines = [
143
+ `// Auto-generated by ${ctx.currentPackageName}`,
144
+ `import type { CSSProperty, CSSSelectors, DefineAutocomplete, Properties, StyleDefinition, StyleItem } from \'${ctx.currentPackageName}\'`,
145
+ "",
146
+ `declare module \'${ctx.currentPackageName}\' {`,
147
+ " interface PikaAugment {",
148
+ " Autocomplete: Autocomplete",
149
+ " Selector: Autocomplete['Selector'] | CSSSelectors",
150
+ " CSSProperty: Autocomplete['ExtraCssProperty'] | CSSProperty",
151
+ " Properties: Properties",
152
+ " StyleDefinition: StyleDefinition",
153
+ " StyleItem: StyleItem",
154
+ " }",
155
+ "}",
156
+ ""
157
+ ];
158
+ lines.push(...generateAutocomplete(ctx));
159
+ lines.push(...generateStyleFn(ctx));
160
+ lines.push(...generateGlobalDeclaration(ctx));
161
+ lines.push(...generateVueDeclaration(ctx));
162
+ lines.push(...await generateOverloadContent(ctx));
163
+ return lines.join("\n");
175
164
  }
176
165
 
166
+ //#endregion
167
+ //#region src/ctx.ts
177
168
  function findFunctionCalls(code, RE) {
178
- const result = [];
179
- let matched = RE.exec(code);
180
- while (matched != null) {
181
- const fnName = matched[1];
182
- const start = matched.index;
183
- let end = start + fnName.length;
184
- let depth = 1;
185
- let inString = false;
186
- while (depth > 0) {
187
- end++;
188
- if (inString === false && code[end] === "(")
189
- depth++;
190
- else if (inString === false && code[end] === ")")
191
- depth--;
192
- else if (inString === false && (code[end] === "'" || code[end] === '"'))
193
- inString = code[end];
194
- else if (inString === code[end])
195
- inString = false;
196
- }
197
- const snippet = code.slice(start, end + 1);
198
- result.push({ fnName, start, end, snippet });
199
- matched = RE.exec(code);
200
- }
201
- return result;
169
+ const result = [];
170
+ let matched = RE.exec(code);
171
+ while (matched != null) {
172
+ const fnName = matched[1];
173
+ const start = matched.index;
174
+ let end = start + fnName.length;
175
+ let depth = 1;
176
+ let inString = false;
177
+ while (depth > 0) {
178
+ end++;
179
+ if (inString === false && code[end] === "(") depth++;
180
+ else if (inString === false && code[end] === ")") depth--;
181
+ else if (inString === false && (code[end] === "'" || code[end] === "\"")) inString = code[end];
182
+ else if (inString === code[end]) inString = false;
183
+ }
184
+ const snippet = code.slice(start, end + 1);
185
+ result.push({
186
+ fnName,
187
+ start,
188
+ end,
189
+ snippet
190
+ });
191
+ matched = RE.exec(code);
192
+ }
193
+ return result;
202
194
  }
203
195
  const ESCAPE_REPLACE_RE = /[.*+?^${}()|[\]\\/]/g;
204
196
  function createFnUtils(fnName) {
205
- const available = {
206
- normal: /* @__PURE__ */ new Set([fnName]),
207
- forceString: /* @__PURE__ */ new Set([`${fnName}.str`, `${fnName}['str']`, `${fnName}["str"]`, `${fnName}[\`str\`]`]),
208
- forceArray: /* @__PURE__ */ new Set([`${fnName}.arr`, `${fnName}['arr']`, `${fnName}["arr"]`, `${fnName}[\`arr\`]`]),
209
- forceInline: /* @__PURE__ */ new Set([`${fnName}.inl`, `${fnName}['inl']`, `${fnName}["inl"]`, `${fnName}[\`inl\`]`]),
210
- // preview
211
- normalPreview: /* @__PURE__ */ new Set([`${fnName}p`]),
212
- forceStringPreview: /* @__PURE__ */ new Set([`${fnName}p.str`, `${fnName}p['str']`, `${fnName}p["str"]`, `${fnName}p[\`str\`]`]),
213
- forceArrayPreview: /* @__PURE__ */ new Set([`${fnName}p.arr`, `${fnName}p['arr']`, `${fnName}p["arr"]`, `${fnName}p[\`arr\`]`]),
214
- forceInlinePreview: /* @__PURE__ */ new Set([`${fnName}p.inl`, `${fnName}p['inl']`, `${fnName}p["inl"]`, `${fnName}p[\`inl\`]`])
215
- };
216
- const RE = new RegExp(`\\b(${Object.values(available).flatMap((s) => [...s].map((f) => `(${f.replace(ESCAPE_REPLACE_RE, "\\$&")})`)).join("|")})\\(`, "g");
217
- return {
218
- isNormal: (fnName2) => available.normal.has(fnName2) || available.normalPreview.has(fnName2),
219
- isForceString: (fnName2) => available.forceString.has(fnName2) || available.forceStringPreview.has(fnName2),
220
- isForceArray: (fnName2) => available.forceArray.has(fnName2) || available.forceArrayPreview.has(fnName2),
221
- isForceInline: (fnName2) => available.forceInline.has(fnName2) || available.forceInlinePreview.has(fnName2),
222
- isPreview: (fnName2) => available.normalPreview.has(fnName2) || available.forceStringPreview.has(fnName2) || available.forceArrayPreview.has(fnName2) || available.forceInlinePreview.has(fnName2),
223
- RE
224
- };
197
+ const available = {
198
+ normal: new Set([fnName]),
199
+ forceString: new Set([
200
+ `${fnName}.str`,
201
+ `${fnName}['str']`,
202
+ `${fnName}["str"]`,
203
+ `${fnName}[\`str\`]`
204
+ ]),
205
+ forceArray: new Set([
206
+ `${fnName}.arr`,
207
+ `${fnName}['arr']`,
208
+ `${fnName}["arr"]`,
209
+ `${fnName}[\`arr\`]`
210
+ ]),
211
+ forceInline: new Set([
212
+ `${fnName}.inl`,
213
+ `${fnName}['inl']`,
214
+ `${fnName}["inl"]`,
215
+ `${fnName}[\`inl\`]`
216
+ ]),
217
+ normalPreview: new Set([`${fnName}p`]),
218
+ forceStringPreview: new Set([
219
+ `${fnName}p.str`,
220
+ `${fnName}p['str']`,
221
+ `${fnName}p["str"]`,
222
+ `${fnName}p[\`str\`]`
223
+ ]),
224
+ forceArrayPreview: new Set([
225
+ `${fnName}p.arr`,
226
+ `${fnName}p['arr']`,
227
+ `${fnName}p["arr"]`,
228
+ `${fnName}p[\`arr\`]`
229
+ ]),
230
+ forceInlinePreview: new Set([
231
+ `${fnName}p.inl`,
232
+ `${fnName}p['inl']`,
233
+ `${fnName}p["inl"]`,
234
+ `${fnName}p[\`inl\`]`
235
+ ])
236
+ };
237
+ return {
238
+ isNormal: (fnName$1) => available.normal.has(fnName$1) || available.normalPreview.has(fnName$1),
239
+ isForceString: (fnName$1) => available.forceString.has(fnName$1) || available.forceStringPreview.has(fnName$1),
240
+ isForceArray: (fnName$1) => available.forceArray.has(fnName$1) || available.forceArrayPreview.has(fnName$1),
241
+ isForceInline: (fnName$1) => available.forceInline.has(fnName$1) || available.forceInlinePreview.has(fnName$1),
242
+ isPreview: (fnName$1) => available.normalPreview.has(fnName$1) || available.forceStringPreview.has(fnName$1) || available.forceArrayPreview.has(fnName$1) || available.forceInlinePreview.has(fnName$1),
243
+ RE: new RegExp(`\\b(${Object.values(available).flatMap((s) => [...s].map((f) => `(${f.replace(ESCAPE_REPLACE_RE, "\\$&")})`)).join("|")})\\(`, "g")
244
+ };
225
245
  }
226
246
  async function createCtx(options) {
227
- const {
228
- cwd,
229
- currentPackageName,
230
- target,
231
- configOrPath,
232
- fnName,
233
- transformedFormat,
234
- tsCodegen,
235
- devCss,
236
- autoCreateConfig
237
- } = options;
238
- setWarnFn((...args) => {
239
- console.warn(`[${currentPackageName}]`, ...args);
240
- });
241
- const devCssFilepath = isAbsolute(devCss) ? resolve(devCss) : join(cwd, devCss);
242
- const tsCodegenFilepath = tsCodegen === false ? null : isAbsolute(tsCodegen) ? resolve(tsCodegen) : join(cwd, tsCodegen);
243
- const inlineConfig = typeof configOrPath === "object" ? configOrPath : null;
244
- const specificConfigPath = typeof configOrPath === "string" ? isAbsolute(configOrPath) ? configOrPath : join(cwd, configOrPath) : null;
245
- const configSources = [
246
- ...specificConfigPath == null ? [] : [specificConfigPath],
247
- ...["pika", "pikacss"].flatMap((name) => ["js", "ts", "cjs", "cts", "mjs", "mts"].map((ext) => `${name}.config.${ext}`)).map((name) => join(cwd, name))
248
- ];
249
- const targetREs = target.map((t) => micromatch.makeRe(t));
250
- const needToTransform = (id) => targetREs.some((re) => re.test(id));
251
- const ctx = {
252
- cwd,
253
- currentPackageName,
254
- fnName,
255
- fnUtils: createFnUtils(fnName),
256
- transformedFormat,
257
- devCssFilepath,
258
- tsCodegenFilepath,
259
- hasVue: isPackageExists("vue", { paths: [cwd] }),
260
- usages: /* @__PURE__ */ new Map(),
261
- hooks: {
262
- styleUpdated: createEventHook(),
263
- tsCodegenUpdated: createEventHook()
264
- },
265
- loadConfig: async () => {
266
- if (inlineConfig != null)
267
- return { config: klona(inlineConfig), file: null };
268
- let resolvedConfigPath = configSources.find((path) => {
269
- const stat = statSync(path, { throwIfNoEntry: false });
270
- return stat != null && stat.isFile();
271
- });
272
- if (resolvedConfigPath == null) {
273
- if (autoCreateConfig === false)
274
- return { config: null, file: null };
275
- resolvedConfigPath = configSources[0];
276
- await mkdir(dirname(resolvedConfigPath), { recursive: true }).catch(() => {
277
- });
278
- const relativeTsCodegenFilepath = tsCodegenFilepath == null ? null : `./${relative(dirname(resolvedConfigPath), tsCodegenFilepath)}`;
279
- await writeFile(resolvedConfigPath, [
280
- `import { defineEngineConfig } from '${currentPackageName}'`,
281
- ...relativeTsCodegenFilepath == null ? [] : [`/** @type {import('${relativeTsCodegenFilepath}')} */`],
282
- "",
283
- "export default defineEngineConfig({",
284
- " // Add your PikaCSS engine config here",
285
- "})"
286
- ].join("\n"));
287
- }
288
- const jiti = createJiti(cwd, {
289
- fsCache: false,
290
- moduleCache: false
291
- });
292
- const config = jiti.evalModule(await readFile(resolvedConfigPath, { encoding: "utf-8" }), { filename: resolvedConfigPath }).default;
293
- return { config: klona(config), file: resolvedConfigPath };
294
- },
295
- init: debounce(async () => {
296
- ctx.isReady = false;
297
- ctx.usages.clear();
298
- const { config, file } = await ctx.loadConfig().catch((error) => {
299
- warn(`Failed to load config file: ${error.message}`, error);
300
- return { config: null, file: null };
301
- });
302
- ctx.resolvedConfigPath = file;
303
- const devPlugin = defineEnginePlugin({
304
- name: "@pikacss/integration:dev",
305
- preflightUpdated: () => ctx.hooks.styleUpdated.trigger(),
306
- atomicStyleAdded: () => ctx.hooks.styleUpdated.trigger(),
307
- autocompleteConfigUpdated: () => ctx.hooks.tsCodegenUpdated.trigger()
308
- });
309
- try {
310
- const _config = config ?? {};
311
- _config.plugins = _config.plugins ?? [];
312
- _config.plugins.unshift(devPlugin);
313
- ctx.engine = await createEngine(_config);
314
- } catch (error) {
315
- warn(`Failed to create engine: ${error.message}. Maybe the config file is invalid, falling back to default config.`, error);
316
- ctx.engine = await createEngine({ plugins: [devPlugin] });
317
- }
318
- await mkdir(dirname(devCssFilepath), { recursive: true }).catch(() => {
319
- });
320
- await writeFile(devCssFilepath, "");
321
- if (tsCodegenFilepath != null) {
322
- await mkdir(dirname(tsCodegenFilepath), { recursive: true }).catch(() => {
323
- });
324
- const content = await generateTsCodegenContent(ctx);
325
- await writeFile(tsCodegenFilepath, content);
326
- }
327
- ctx.isReady = true;
328
- }, 300),
329
- isReady: false,
330
- configSources,
331
- resolvedConfigPath: null,
332
- engine: null,
333
- transform: async (code, id) => {
334
- try {
335
- if (ctx.isReady === false || !needToTransform(id)) {
336
- return;
337
- }
338
- ctx.usages.delete(id);
339
- const functionCalls = findFunctionCalls(code, ctx.fnUtils.RE);
340
- if (functionCalls.length === 0)
341
- return;
342
- const usages = [];
343
- const transformed = new MagicString(code);
344
- for (const fnCall of functionCalls) {
345
- const functionCallStr = fnCall.snippet;
346
- const argsStr = `[${functionCallStr.slice(fnCall.fnName.length + 1, -1)}]`;
347
- const args = new Function(`return ${argsStr}`)();
348
- const names = await ctx.engine.use(...args);
349
- const usage = {
350
- atomicStyleIds: names,
351
- params: args
352
- };
353
- usages.push(usage);
354
- let transformedContent;
355
- if (ctx.fnUtils.isNormal(fnCall.fnName)) {
356
- transformedContent = ctx.transformedFormat === "array" ? `[${names.map((n) => `'${n}'`).join(", ")}]` : ctx.transformedFormat === "string" ? `'${names.join(" ")}'` : names.join(" ");
357
- } else if (ctx.fnUtils.isForceString(fnCall.fnName)) {
358
- transformedContent = `'${names.join(" ")}'`;
359
- } else if (ctx.fnUtils.isForceArray(fnCall.fnName)) {
360
- transformedContent = `[${names.map((n) => `'${n}'`).join(", ")}]`;
361
- } else if (ctx.fnUtils.isForceInline(fnCall.fnName)) {
362
- transformedContent = names.join(" ");
363
- } else {
364
- throw new Error(`Unexpected function name: ${fnCall.fnName}`);
365
- }
366
- transformed.update(fnCall.start, fnCall.end + 1, transformedContent);
367
- }
368
- ctx.usages.set(id, usages);
369
- ctx.hooks.styleUpdated.trigger();
370
- ctx.hooks.tsCodegenUpdated.trigger();
371
- return {
372
- code: transformed.toString(),
373
- map: transformed.generateMap({ hires: true })
374
- };
375
- } catch (error) {
376
- warn(`Failed to transform code: ${error.message}`, error);
377
- return void 0;
378
- }
379
- },
380
- getCssContent: async (isDev) => {
381
- if (ctx.isReady === false)
382
- return null;
383
- const atomicStyleIds = [...new Set([...ctx.usages.values()].flatMap((i) => [...new Set(i.flatMap((i2) => i2.atomicStyleIds))]))];
384
- const css = [
385
- `/* Auto-generated by ${ctx.currentPackageName} */`,
386
- await ctx.engine.renderPreflights(isDev),
387
- await ctx.engine.renderAtomicStyles(isDev, { atomicStyleIds })
388
- ].join("\n").trim();
389
- return css;
390
- },
391
- getTsCodegenContent: async () => {
392
- if (ctx.isReady === false || ctx.tsCodegenFilepath == null)
393
- return null;
394
- const content = await generateTsCodegenContent(ctx);
395
- return content;
396
- },
397
- writeDevCssFile: debounce(async () => {
398
- const content = await ctx.getCssContent(true);
399
- if (content == null)
400
- return;
401
- await writeFile(ctx.devCssFilepath, content);
402
- }, 300),
403
- writeTsCodegenFile: debounce(async () => {
404
- const content = await ctx.getTsCodegenContent();
405
- if (ctx.tsCodegenFilepath == null || content == null)
406
- return;
407
- await writeFile(ctx.tsCodegenFilepath, content);
408
- }, 300)
409
- };
410
- await ctx.init();
411
- return ctx;
247
+ const { cwd, currentPackageName, target, configOrPath, fnName, transformedFormat, tsCodegen, devCss, autoCreateConfig } = options;
248
+ setWarnFn((...args) => {
249
+ console.warn(`[${currentPackageName}]`, ...args);
250
+ });
251
+ const devCssFilepath = isAbsolute(devCss) ? resolve(devCss) : join(cwd, devCss);
252
+ const tsCodegenFilepath = tsCodegen === false ? null : isAbsolute(tsCodegen) ? resolve(tsCodegen) : join(cwd, tsCodegen);
253
+ const inlineConfig = typeof configOrPath === "object" ? configOrPath : null;
254
+ const specificConfigPath = typeof configOrPath === "string" ? isAbsolute(configOrPath) ? configOrPath : join(cwd, configOrPath) : null;
255
+ const configSources = [...specificConfigPath == null ? [] : [specificConfigPath], ...["pika", "pikacss"].flatMap((name) => [
256
+ "js",
257
+ "ts",
258
+ "cjs",
259
+ "cts",
260
+ "mjs",
261
+ "mts"
262
+ ].map((ext) => `${name}.config.${ext}`)).map((name) => join(cwd, name))];
263
+ const targetREs = target.map((t) => micromatch.makeRe(t));
264
+ const needToTransform = (id) => targetREs.some((re) => re.test(id));
265
+ const ctx = {
266
+ cwd,
267
+ currentPackageName,
268
+ fnName,
269
+ fnUtils: createFnUtils(fnName),
270
+ transformedFormat,
271
+ devCssFilepath,
272
+ tsCodegenFilepath,
273
+ hasVue: isPackageExists("vue", { paths: [cwd] }),
274
+ usages: /* @__PURE__ */ new Map(),
275
+ hooks: {
276
+ styleUpdated: createEventHook(),
277
+ tsCodegenUpdated: createEventHook()
278
+ },
279
+ loadConfig: async () => {
280
+ if (inlineConfig != null) return {
281
+ config: klona(inlineConfig),
282
+ file: null
283
+ };
284
+ let resolvedConfigPath = configSources.find((path) => {
285
+ const stat = statSync(path, { throwIfNoEntry: false });
286
+ return stat != null && stat.isFile();
287
+ });
288
+ if (resolvedConfigPath == null) {
289
+ if (autoCreateConfig === false) return {
290
+ config: null,
291
+ file: null
292
+ };
293
+ resolvedConfigPath = configSources[0];
294
+ await mkdir(dirname(resolvedConfigPath), { recursive: true }).catch(() => {});
295
+ const relativeTsCodegenFilepath = tsCodegenFilepath == null ? null : `./${relative(dirname(resolvedConfigPath), tsCodegenFilepath)}`;
296
+ await writeFile(resolvedConfigPath, [
297
+ `import { defineEngineConfig } from '${currentPackageName}'`,
298
+ ...relativeTsCodegenFilepath == null ? [] : [`/** @type {import('${relativeTsCodegenFilepath}')} */`],
299
+ "",
300
+ "export default defineEngineConfig({",
301
+ " // Add your PikaCSS engine config here",
302
+ "})"
303
+ ].join("\n"));
304
+ }
305
+ const config = createJiti(cwd, {
306
+ fsCache: false,
307
+ moduleCache: false
308
+ }).evalModule(await readFile(resolvedConfigPath, { encoding: "utf-8" }), { filename: resolvedConfigPath }).default;
309
+ return {
310
+ config: klona(config),
311
+ file: resolvedConfigPath
312
+ };
313
+ },
314
+ init: debounce(async () => {
315
+ ctx.isReady = false;
316
+ ctx.usages.clear();
317
+ const { config, file } = await ctx.loadConfig().catch((error) => {
318
+ warn(`Failed to load config file: ${error.message}`, error);
319
+ return {
320
+ config: null,
321
+ file: null
322
+ };
323
+ });
324
+ ctx.resolvedConfigPath = file;
325
+ const devPlugin = defineEnginePlugin({
326
+ name: "@pikacss/integration:dev",
327
+ preflightUpdated: () => ctx.hooks.styleUpdated.trigger(),
328
+ atomicStyleAdded: () => ctx.hooks.styleUpdated.trigger(),
329
+ autocompleteConfigUpdated: () => ctx.hooks.tsCodegenUpdated.trigger()
330
+ });
331
+ try {
332
+ const _config = config ?? {};
333
+ _config.plugins = _config.plugins ?? [];
334
+ _config.plugins.unshift(devPlugin);
335
+ ctx.engine = await createEngine(_config);
336
+ } catch (error) {
337
+ warn(`Failed to create engine: ${error.message}. Maybe the config file is invalid, falling back to default config.`, error);
338
+ ctx.engine = await createEngine({ plugins: [devPlugin] });
339
+ }
340
+ await mkdir(dirname(devCssFilepath), { recursive: true }).catch(() => {});
341
+ await writeFile(devCssFilepath, "");
342
+ if (tsCodegenFilepath != null) {
343
+ await mkdir(dirname(tsCodegenFilepath), { recursive: true }).catch(() => {});
344
+ await writeFile(tsCodegenFilepath, await generateTsCodegenContent(ctx));
345
+ }
346
+ ctx.isReady = true;
347
+ }, 300),
348
+ isReady: false,
349
+ configSources,
350
+ resolvedConfigPath: null,
351
+ engine: null,
352
+ transform: async (code, id) => {
353
+ try {
354
+ if (ctx.isReady === false || !needToTransform(id)) return;
355
+ ctx.usages.delete(id);
356
+ const functionCalls = findFunctionCalls(code, ctx.fnUtils.RE);
357
+ if (functionCalls.length === 0) return;
358
+ const usages = [];
359
+ const transformed = new MagicString(code);
360
+ for (const fnCall of functionCalls) {
361
+ const argsStr = `[${fnCall.snippet.slice(fnCall.fnName.length + 1, -1)}]`;
362
+ const args = new Function(`return ${argsStr}`)();
363
+ const names = await ctx.engine.use(...args);
364
+ const usage = {
365
+ atomicStyleIds: names,
366
+ params: args
367
+ };
368
+ usages.push(usage);
369
+ let transformedContent;
370
+ if (ctx.fnUtils.isNormal(fnCall.fnName)) transformedContent = ctx.transformedFormat === "array" ? `[${names.map((n) => `'${n}'`).join(", ")}]` : ctx.transformedFormat === "string" ? `'${names.join(" ")}'` : names.join(" ");
371
+ else if (ctx.fnUtils.isForceString(fnCall.fnName)) transformedContent = `'${names.join(" ")}'`;
372
+ else if (ctx.fnUtils.isForceArray(fnCall.fnName)) transformedContent = `[${names.map((n) => `'${n}'`).join(", ")}]`;
373
+ else if (ctx.fnUtils.isForceInline(fnCall.fnName)) transformedContent = names.join(" ");
374
+ else throw new Error(`Unexpected function name: ${fnCall.fnName}`);
375
+ transformed.update(fnCall.start, fnCall.end + 1, transformedContent);
376
+ }
377
+ ctx.usages.set(id, usages);
378
+ ctx.hooks.styleUpdated.trigger();
379
+ ctx.hooks.tsCodegenUpdated.trigger();
380
+ return {
381
+ code: transformed.toString(),
382
+ map: transformed.generateMap({ hires: true })
383
+ };
384
+ } catch (error) {
385
+ warn(`Failed to transform code: ${error.message}`, error);
386
+ return;
387
+ }
388
+ },
389
+ getCssContent: async (isDev) => {
390
+ if (ctx.isReady === false) return null;
391
+ const atomicStyleIds = [...new Set([...ctx.usages.values()].flatMap((i) => [...new Set(i.flatMap((i$1) => i$1.atomicStyleIds))]))];
392
+ return [
393
+ `/* Auto-generated by ${ctx.currentPackageName} */`,
394
+ await ctx.engine.renderPreflights(isDev),
395
+ await ctx.engine.renderAtomicStyles(isDev, { atomicStyleIds })
396
+ ].join("\n").trim();
397
+ },
398
+ getTsCodegenContent: async () => {
399
+ if (ctx.isReady === false || ctx.tsCodegenFilepath == null) return null;
400
+ return await generateTsCodegenContent(ctx);
401
+ },
402
+ writeDevCssFile: debounce(async () => {
403
+ const content = await ctx.getCssContent(true);
404
+ if (content == null) return;
405
+ await writeFile(ctx.devCssFilepath, content);
406
+ }, 300),
407
+ writeTsCodegenFile: debounce(async () => {
408
+ const content = await ctx.getTsCodegenContent();
409
+ if (ctx.tsCodegenFilepath == null || content == null) return;
410
+ await writeFile(ctx.tsCodegenFilepath, content);
411
+ }, 300)
412
+ };
413
+ await ctx.init();
414
+ return ctx;
412
415
  }
413
416
 
414
- export { createCtx };
417
+ //#endregion
418
+ export { createCtx };