tailwindcss-patch 0.0.0 → 0.0.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 CHANGED
@@ -1 +1,40 @@
1
- # tailwindcss-patch (WIP)
1
+ # tailwindcss-patch
2
+
3
+ get tailwindcss context at runtime!
4
+
5
+ ## Setup
6
+
7
+ 1. Install package
8
+
9
+ ```sh
10
+ <yarn|npm|pnpm> add -D ts-patch
11
+ ```
12
+
13
+ 2. Patch tailwindcss
14
+
15
+ ```sh
16
+ npx tw-patch
17
+ ```
18
+
19
+ 3. Add `prepare` script (keeps patch persisted after npm install)
20
+
21
+ `package.json`
22
+
23
+ ```json
24
+ {
25
+ /* ... */
26
+ "scripts": {
27
+ "prepare": "tw-patch"
28
+ }
29
+ }
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ```js
35
+ import { getContexts , getClassCacheSet } from 'tailwindcss-patch'
36
+ // get all contexts at runtime
37
+ getContexts()
38
+ // get all class generated by tailwindcss utilities
39
+ getClassCacheSet()
40
+ ```
package/bin/tw-patch.js CHANGED
@@ -1 +1,7 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
+ const fs = require('fs')
3
+ const path = require('path')
4
+ const cliPath = path.resolve(__dirname, '../dist/cli.js')
5
+ if (fs.existsSync(cliPath)) {
6
+ require(cliPath)
7
+ }
package/dist/cli.js ADDED
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ var patcher = require('./patcher-e9a851ca.js');
4
+ require('path');
5
+ require('fs');
6
+ require('semver');
7
+ require('@babel/types');
8
+ require('@babel/generator');
9
+ require('@babel/parser');
10
+ require('@babel/traverse');
11
+
12
+ const patch = patcher.createPatch({});
13
+ patch();
package/dist/index.js CHANGED
@@ -1,2 +1,56 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var path = require('path');
6
+ var fs = require('fs');
7
+ var patcher = require('./patcher-e9a851ca.js');
8
+ require('semver');
9
+ require('@babel/types');
10
+ require('@babel/generator');
11
+ require('@babel/parser');
12
+ require('@babel/traverse');
13
+
14
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
15
+
16
+ var path__default = /*#__PURE__*/_interopDefaultCompat(path);
17
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
18
+
19
+ function getContexts() {
20
+ const distPath = path__default["default"].dirname(require.resolve('tailwindcss/lib'));
21
+ let injectFilePath = path__default["default"].join(distPath, 'plugin.js');
22
+ if (!fs__default["default"].existsSync(injectFilePath)) {
23
+ injectFilePath = path__default["default"].join(distPath, 'index.js');
24
+ }
25
+ const mo = require(injectFilePath);
26
+ if (mo.contextRef) {
27
+ return mo.contextRef.value;
28
+ }
29
+ return [];
30
+ }
31
+ function getClassCaches() {
32
+ const contexts = getContexts();
33
+ return contexts.map((x) => x.classCache);
34
+ }
35
+ function getClassCacheSet() {
36
+ const classCaches = getClassCaches();
37
+ const classSet = new Set();
38
+ for (let i = 0; i < classCaches.length; i++) {
39
+ const classCacheMap = classCaches[i];
40
+ const keys = classCacheMap.keys();
41
+ for (const key of keys) {
42
+ classSet.add(key);
43
+ }
44
+ }
45
+ return classSet;
46
+ }
47
+
48
+ exports.createPatch = patcher.createPatch;
49
+ exports.getInstalledPkgJsonPath = patcher.getInstalledPkgJsonPath;
50
+ exports.inspectPostcssPlugin = patcher.inspectPostcssPlugin;
51
+ exports.inspectProcessTailwindFeaturesReturnContext = patcher.inspectProcessTailwindFeaturesReturnContext;
52
+ exports.internalPatch = patcher.internalPatch;
53
+ exports.monkeyPatchForExposingContext = patcher.monkeyPatchForExposingContext;
54
+ exports.getClassCacheSet = getClassCacheSet;
55
+ exports.getClassCaches = getClassCaches;
56
+ exports.getContexts = getContexts;
@@ -0,0 +1,293 @@
1
+ 'use strict';
2
+
3
+ var path = require('path');
4
+ var fs = require('fs');
5
+ var semver = require('semver');
6
+ var t = require('@babel/types');
7
+ var generate = require('@babel/generator');
8
+ var parser = require('@babel/parser');
9
+ var traverse = require('@babel/traverse');
10
+
11
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
+
13
+ function _interopNamespaceCompat(e) {
14
+ if (e && typeof e === 'object' && 'default' in e) return e;
15
+ var n = Object.create(null);
16
+ if (e) {
17
+ Object.keys(e).forEach(function (k) {
18
+ if (k !== 'default') {
19
+ var d = Object.getOwnPropertyDescriptor(e, k);
20
+ Object.defineProperty(n, k, d.get ? d : {
21
+ enumerable: true,
22
+ get: function () { return e[k]; }
23
+ });
24
+ }
25
+ });
26
+ }
27
+ n["default"] = e;
28
+ return Object.freeze(n);
29
+ }
30
+
31
+ var path__default = /*#__PURE__*/_interopDefaultCompat(path);
32
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
33
+ var t__namespace = /*#__PURE__*/_interopNamespaceCompat(t);
34
+ var generate__default = /*#__PURE__*/_interopDefaultCompat(generate);
35
+ var traverse__default = /*#__PURE__*/_interopDefaultCompat(traverse);
36
+
37
+ function inspectProcessTailwindFeaturesReturnContext(content) {
38
+ const ast = parser.parse(content);
39
+ let hasPatched = false;
40
+ traverse__default["default"](ast, {
41
+ FunctionDeclaration(p) {
42
+ var _a, _b;
43
+ const n = p.node;
44
+ if (((_a = n.id) === null || _a === void 0 ? void 0 : _a.name) === 'processTailwindFeatures') {
45
+ if (n.body.body.length === 1 && n.body.body[0].type === 'ReturnStatement') {
46
+ const rts = n.body.body[0];
47
+ if (t__namespace.isFunctionExpression(rts.argument)) {
48
+ const body = rts.argument.body.body;
49
+ const lastStatement = body[body.length - 1];
50
+ hasPatched = lastStatement.type === 'ReturnStatement' && ((_b = lastStatement.argument) === null || _b === void 0 ? void 0 : _b.type) === 'Identifier' && lastStatement.argument.name === 'context';
51
+ if (!hasPatched) {
52
+ const rts = t__namespace.returnStatement(t__namespace.identifier('context'));
53
+ body.push(rts);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ });
60
+ return {
61
+ code: hasPatched ? content : generate__default["default"](ast).code,
62
+ hasPatched
63
+ };
64
+ }
65
+ function inspectPostcssPlugin(content) {
66
+ const ast = parser.parse(content);
67
+ const exportKey = 'contextRef';
68
+ const variableName = 'contextRef';
69
+ const valueKey = 'value';
70
+ let hasPatched = false;
71
+ traverse__default["default"](ast, {
72
+ Program(p) {
73
+ const n = p.node;
74
+ const idx = n.body.findIndex((x) => {
75
+ var _a;
76
+ return (x.type === 'ExpressionStatement' &&
77
+ x.expression.type === 'AssignmentExpression' &&
78
+ x.expression.left.type === 'MemberExpression' &&
79
+ x.expression.right.type === 'FunctionExpression' &&
80
+ ((_a = x.expression.right.id) === null || _a === void 0 ? void 0 : _a.name) === 'tailwindcss');
81
+ });
82
+ if (idx > -1) {
83
+ const prevStatement = n.body[idx - 1];
84
+ const lastStatement = n.body[n.body.length - 1];
85
+ const hasPatchedCondition0 = prevStatement &&
86
+ prevStatement.type === 'VariableDeclaration' &&
87
+ prevStatement.declarations.length === 1 &&
88
+ prevStatement.declarations[0].id.type === 'Identifier' &&
89
+ prevStatement.declarations[0].id.name === variableName;
90
+ const hasPatchedCondition1 = lastStatement.type === 'ExpressionStatement' &&
91
+ lastStatement.expression.type === 'AssignmentExpression' &&
92
+ lastStatement.expression.right.type === 'Identifier' &&
93
+ lastStatement.expression.right.name === variableName;
94
+ hasPatched = hasPatchedCondition0 || hasPatchedCondition1;
95
+ if (!hasPatched) {
96
+ const statement = t__namespace.variableDeclaration('const', [
97
+ t__namespace.variableDeclarator(t__namespace.identifier(variableName), t__namespace.objectExpression([t__namespace.objectProperty(t__namespace.identifier(valueKey), t__namespace.arrayExpression())]))
98
+ ]);
99
+ n.body.splice(idx, 0, statement);
100
+ n.body.push(t__namespace.expressionStatement(t__namespace.assignmentExpression('=', t__namespace.memberExpression(t__namespace.memberExpression(t__namespace.identifier('module'), t__namespace.identifier('exports')), t__namespace.identifier(exportKey)), t__namespace.identifier(variableName))));
101
+ }
102
+ }
103
+ },
104
+ FunctionExpression(p) {
105
+ var _a, _b;
106
+ if (hasPatched) {
107
+ return;
108
+ }
109
+ const n = p.node;
110
+ if (((_a = n.id) === null || _a === void 0 ? void 0 : _a.name) === 'tailwindcss') {
111
+ if (n.body.body.length === 1 && n.body.body[0].type === 'ReturnStatement') {
112
+ const returnStatement = n.body.body[0];
113
+ if (((_b = returnStatement.argument) === null || _b === void 0 ? void 0 : _b.type) === 'ObjectExpression' && returnStatement.argument.properties.length === 2) {
114
+ const properties = returnStatement.argument.properties;
115
+ if (properties[0].type === 'ObjectProperty' && properties[1].type === 'ObjectProperty') {
116
+ const keyMatched = properties[0].key.type === 'Identifier' && properties[0].key.name === 'postcssPlugin';
117
+ const pluginsMatched = properties[1].key.type === 'Identifier' && properties[1].key.name === 'plugins';
118
+ if (pluginsMatched &&
119
+ keyMatched &&
120
+ properties[1].value.type === 'CallExpression' &&
121
+ properties[1].value.callee.type === 'MemberExpression' &&
122
+ properties[1].value.callee.object.type === 'ArrayExpression') {
123
+ const pluginsCode = properties[1].value.callee.object.elements;
124
+ if (pluginsCode[1] && pluginsCode[1].type === 'FunctionExpression') {
125
+ const targetBlockStatement = pluginsCode[1].body;
126
+ const lastStatement = targetBlockStatement.body[targetBlockStatement.body.length - 1];
127
+ if (lastStatement.type === 'ExpressionStatement') {
128
+ const newExpressionStatement = t__namespace.expressionStatement(t__namespace.callExpression(t__namespace.memberExpression(t__namespace.memberExpression(t__namespace.identifier(variableName), t__namespace.identifier('value')), t__namespace.identifier('push')), [lastStatement.expression]));
129
+ targetBlockStatement.body[targetBlockStatement.body.length - 1] = newExpressionStatement;
130
+ }
131
+ const ifIdx = targetBlockStatement.body.findIndex((x) => x.type === 'IfStatement');
132
+ if (ifIdx > -1) {
133
+ const ifRoot = targetBlockStatement.body[ifIdx];
134
+ if (ifRoot.consequent.type === 'BlockStatement' && ifRoot.consequent.body[1] && ifRoot.consequent.body[1].type === 'ForOfStatement') {
135
+ const forOf = ifRoot.consequent.body[1];
136
+ if (forOf.body.type === 'BlockStatement' && forOf.body.body.length === 1 && forOf.body.body[0].type === 'IfStatement') {
137
+ const if2 = forOf.body.body[0];
138
+ if (if2.consequent.type === 'BlockStatement' && if2.consequent.body.length === 1 && if2.consequent.body[0].type === 'ExpressionStatement') {
139
+ const target = if2.consequent.body[0];
140
+ const newExpressionStatement = t__namespace.expressionStatement(t__namespace.callExpression(t__namespace.memberExpression(t__namespace.memberExpression(t__namespace.identifier(variableName), t__namespace.identifier('value')), t__namespace.identifier('push')), [target.expression]));
141
+ if2.consequent.body[0] = newExpressionStatement;
142
+ }
143
+ }
144
+ }
145
+ }
146
+ targetBlockStatement.body.unshift(t__namespace.expressionStatement(t__namespace.assignmentExpression('=', t__namespace.memberExpression(t__namespace.memberExpression(t__namespace.identifier(variableName), t__namespace.identifier(valueKey)), t__namespace.identifier('length')), t__namespace.numericLiteral(0))));
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
153
+ }
154
+ });
155
+ return {
156
+ code: hasPatched ? content : generate__default["default"](ast).code,
157
+ hasPatched
158
+ };
159
+ }
160
+
161
+ function isObject(value) {
162
+ return value !== null && typeof value === "object";
163
+ }
164
+ function _defu(baseObject, defaults, namespace = ".", merger) {
165
+ if (!isObject(defaults)) {
166
+ return _defu(baseObject, {}, namespace, merger);
167
+ }
168
+ const object = Object.assign({}, defaults);
169
+ for (const key in baseObject) {
170
+ if (key === "__proto__" || key === "constructor") {
171
+ continue;
172
+ }
173
+ const value = baseObject[key];
174
+ if (value === null || value === void 0) {
175
+ continue;
176
+ }
177
+ if (merger && merger(object, key, value, namespace)) {
178
+ continue;
179
+ }
180
+ if (Array.isArray(value) && Array.isArray(object[key])) {
181
+ object[key] = [...value, ...object[key]];
182
+ } else if (isObject(value) && isObject(object[key])) {
183
+ object[key] = _defu(
184
+ value,
185
+ object[key],
186
+ (namespace ? `${namespace}.` : "") + key.toString(),
187
+ merger
188
+ );
189
+ } else {
190
+ object[key] = value;
191
+ }
192
+ }
193
+ return object;
194
+ }
195
+ function createDefu(merger) {
196
+ return (...arguments_) => (
197
+ // eslint-disable-next-line unicorn/no-array-reduce
198
+ arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
199
+ );
200
+ }
201
+ const defu = createDefu();
202
+
203
+ const defaultOptions = {
204
+ overwrite: true
205
+ };
206
+
207
+ function ensureFileContent(filepaths) {
208
+ if (typeof filepaths === 'string') {
209
+ filepaths = [filepaths];
210
+ }
211
+ let content;
212
+ for (let i = 0; i < filepaths.length; i++) {
213
+ const filepath = filepaths[i];
214
+ if (fs__default["default"].existsSync(filepath)) {
215
+ content = fs__default["default"].readFileSync(filepath, {
216
+ encoding: 'utf-8'
217
+ });
218
+ break;
219
+ }
220
+ }
221
+ return content;
222
+ }
223
+
224
+ function getInstalledPkgJsonPath(options) {
225
+ try {
226
+ const tmpJsonPath = require.resolve(`tailwindcss/package.json`, {
227
+ paths: options.paths
228
+ });
229
+ const pkgJson = require(tmpJsonPath);
230
+ if (semver.gte(pkgJson.version, '3.0.0')) {
231
+ return tmpJsonPath;
232
+ }
233
+ }
234
+ catch (error) {
235
+ if (error.code === 'MODULE_NOT_FOUND') {
236
+ console.warn('没有找到`tailwindcss`包,请确认是否安装。');
237
+ }
238
+ }
239
+ }
240
+ function createPatch(options) {
241
+ const opt = defu(options, defaultOptions);
242
+ return () => {
243
+ try {
244
+ return internalPatch(getInstalledPkgJsonPath(options), opt);
245
+ }
246
+ catch (error) {
247
+ console.warn(`patch tailwindcss failed:` + error.message);
248
+ }
249
+ };
250
+ }
251
+ function monkeyPatchForExposingContext(rootDir, opt) {
252
+ const processTailwindFeaturesFilePath = path__default["default"].resolve(rootDir, 'lib/processTailwindFeatures.js');
253
+ const processTailwindFeaturesContent = ensureFileContent(processTailwindFeaturesFilePath);
254
+ const result = {};
255
+ if (processTailwindFeaturesContent) {
256
+ const { code, hasPatched } = inspectProcessTailwindFeaturesReturnContext(processTailwindFeaturesContent);
257
+ if (!hasPatched && opt.overwrite) {
258
+ fs__default["default"].writeFileSync(processTailwindFeaturesFilePath, code, {
259
+ encoding: 'utf-8'
260
+ });
261
+ console.log('patch tailwindcss processTailwindFeatures for return content successfully!');
262
+ }
263
+ result.processTailwindFeatures = code;
264
+ }
265
+ const pluginFilePath = path__default["default"].resolve(rootDir, 'lib/plugin.js');
266
+ const indexFilePath = path__default["default"].resolve(rootDir, 'lib/index.js');
267
+ const pluginContent = ensureFileContent([pluginFilePath, indexFilePath]);
268
+ if (pluginContent) {
269
+ const { code, hasPatched } = inspectPostcssPlugin(pluginContent);
270
+ if (!hasPatched && opt.overwrite) {
271
+ fs__default["default"].writeFileSync(pluginFilePath, code, {
272
+ encoding: 'utf-8'
273
+ });
274
+ console.log('patch tailwindcss for expose runtime content successfully!');
275
+ }
276
+ result.plugin = code;
277
+ }
278
+ return result;
279
+ }
280
+ function internalPatch(pkgJsonPath, options) {
281
+ if (pkgJsonPath) {
282
+ const rootDir = path__default["default"].dirname(pkgJsonPath);
283
+ const result = monkeyPatchForExposingContext(rootDir, options);
284
+ return result;
285
+ }
286
+ }
287
+
288
+ exports.createPatch = createPatch;
289
+ exports.getInstalledPkgJsonPath = getInstalledPkgJsonPath;
290
+ exports.inspectPostcssPlugin = inspectPostcssPlugin;
291
+ exports.inspectProcessTailwindFeaturesReturnContext = inspectProcessTailwindFeaturesReturnContext;
292
+ exports.internalPatch = internalPatch;
293
+ exports.monkeyPatchForExposingContext = monkeyPatchForExposingContext;
@@ -0,0 +1,4 @@
1
+ import generate from '@babel/generator';
2
+ import { parse } from '@babel/parser';
3
+ import traverse from '@babel/traverse';
4
+ export { generate, parse, traverse };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { PatchOptions } from './type';
2
+ export declare const defaultOptions: PatchOptions;
@@ -0,0 +1,8 @@
1
+ import type { Rule } from 'postcss';
2
+ export declare function getContexts(): any[];
3
+ export declare function getClassCaches(): Map<string, ({
4
+ layer: string;
5
+ options: Record<string, any>;
6
+ sort: Record<string, any>;
7
+ } | Rule)[]>[];
8
+ export declare function getClassCacheSet(): Set<string>;
@@ -0,0 +1,3 @@
1
+ export * from './exposeContext';
2
+ export * from './inspector';
3
+ export * from './patcher';
@@ -0,0 +1,8 @@
1
+ export declare function inspectProcessTailwindFeaturesReturnContext(content: string): {
2
+ code: string;
3
+ hasPatched: boolean;
4
+ };
5
+ export declare function inspectPostcssPlugin(content: string): {
6
+ code: string;
7
+ hasPatched: boolean;
8
+ };
@@ -0,0 +1,8 @@
1
+ import type { PatchOptions, InternalPatchOptions } from './type';
2
+ export declare function getInstalledPkgJsonPath(options: PatchOptions): string | undefined;
3
+ export declare function createPatch(options: PatchOptions): () => any;
4
+ export declare function monkeyPatchForExposingContext(rootDir: string, opt: InternalPatchOptions): {
5
+ processTailwindFeatures?: string | undefined;
6
+ plugin?: string | undefined;
7
+ };
8
+ export declare function internalPatch(pkgJsonPath: string | undefined, options: InternalPatchOptions): any | undefined;
@@ -0,0 +1,8 @@
1
+ export interface PatchOptions {
2
+ overwrite?: boolean;
3
+ paths?: string[];
4
+ }
5
+ export interface InternalPatchOptions {
6
+ overwrite: boolean;
7
+ paths?: string[];
8
+ }
@@ -0,0 +1 @@
1
+ export declare function ensureFileContent(filepaths: string | string[]): string | undefined;
package/package.json CHANGED
@@ -1,28 +1,51 @@
1
1
  {
2
2
  "name": "tailwindcss-patch",
3
- "version": "0.0.0",
4
- "description": "",
3
+ "version": "0.0.1",
4
+ "description": "patch tailwindcss for exposing context",
5
5
  "main": "dist/index.js",
6
- "module": "dist/index.es.js",
7
6
  "types": "dist/types/index.d.ts",
8
7
  "bin": {
9
- "tw-patch": "bin/tw-patch.js"
8
+ "tw-patch": "bin/tw-patch.js",
9
+ "tailwindcss-patch": "bin/tw-patch.js"
10
10
  },
11
11
  "files": [
12
- "dist"
12
+ "dist",
13
+ "bin"
13
14
  ],
14
- "keywords": [],
15
- "author": "",
16
- "license": "ISC",
15
+ "keywords": [
16
+ "tailwindcss",
17
+ "patch"
18
+ ],
19
+ "author": "SonOfMagic <qq1324318532@gmail.com>",
20
+ "license": "MIT",
17
21
  "publishConfig": {
18
22
  "access": "public",
19
23
  "registry": "https://registry.npmjs.org/"
20
24
  },
25
+ "devDependencies": {
26
+ "@types/babel__generator": "^7.6.4",
27
+ "@types/babel__traverse": "^7.18.3",
28
+ "@types/semver": "^7.3.13",
29
+ "defu": "^6.1.2",
30
+ "pkg-types": "^1.0.2",
31
+ "postcss": "^8.4.21",
32
+ "tailwindcss": "^3.3.1"
33
+ },
34
+ "dependencies": {
35
+ "@babel/generator": "^7.21.4",
36
+ "@babel/parser": "^7.21.4",
37
+ "@babel/traverse": "^7.21.4",
38
+ "@babel/types": "^7.21.4",
39
+ "semver": "^7.3.8"
40
+ },
21
41
  "scripts": {
22
42
  "dev": "cross-env NODE_ENV=development rollup -cw",
23
43
  "build": "cross-env NODE_ENV=production rollup -c",
24
44
  "dev:tsc": "tsc -p tsconfig.json --sourceMap",
25
45
  "build:tsc": "tsc -p tsconfig.json",
26
- "test": "jest"
46
+ "test": "jest",
47
+ "postinstall": "echo postinstall",
48
+ "preinstall": "npx only-allow pnpm",
49
+ "patch": "ts-node src/cli.ts"
27
50
  }
28
51
  }
package/dist/index.es.js DELETED
@@ -1 +0,0 @@
1
-