gtx-cli 0.0.1 → 0.0.2
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 +4 -7
- package/dist/api/waitForUpdates.d.ts +1 -0
- package/dist/api/waitForUpdates.js +89 -0
- package/dist/cli/base.d.ts +3 -0
- package/dist/cli/base.js +11 -0
- package/dist/cli/next.d.ts +18 -0
- package/dist/cli/next.js +162 -0
- package/dist/cli/react.d.ts +29 -0
- package/dist/cli/react.js +550 -0
- package/dist/console/console.d.ts +8 -0
- package/dist/console/console.js +65 -0
- package/dist/console/errors.d.ts +1 -0
- package/dist/console/errors.js +4 -0
- package/dist/console/index.d.ts +1 -0
- package/dist/console/index.js +2 -0
- package/dist/console/warnings.d.ts +7 -0
- package/dist/console/warnings.js +47 -0
- package/dist/fs/config/loadConfig.d.ts +1 -0
- package/dist/fs/config/loadConfig.js +15 -0
- package/dist/fs/config/setupConfig.d.ts +8 -0
- package/dist/fs/config/setupConfig.js +37 -0
- package/dist/fs/config/updateConfig.d.ts +10 -0
- package/dist/fs/config/updateConfig.js +33 -0
- package/dist/fs/findFilepath.d.ts +15 -0
- package/dist/fs/findFilepath.js +49 -0
- package/dist/fs/findJsxFilepath.d.ts +7 -0
- package/dist/fs/findJsxFilepath.js +36 -0
- package/dist/fs/index.d.ts +1 -0
- package/dist/fs/index.js +2 -0
- package/dist/fs/loadJSON.d.ts +6 -0
- package/dist/fs/loadJSON.js +23 -0
- package/dist/fs/saveTranslations.d.ts +3 -0
- package/dist/fs/saveTranslations.js +57 -0
- package/dist/hooks/postProcess.d.ts +4 -0
- package/dist/hooks/postProcess.js +101 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +84 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +11 -0
- package/dist/next/config/parseNextConfig.d.ts +10 -0
- package/dist/next/config/parseNextConfig.js +55 -0
- package/dist/next/jsx/utils.d.ts +7 -0
- package/dist/next/jsx/utils.js +82 -0
- package/dist/next/parse/handleInitGT.d.ts +5 -0
- package/dist/next/parse/handleInitGT.js +167 -0
- package/dist/next/parse/index.d.ts +4 -0
- package/dist/next/parse/index.js +14 -0
- package/dist/next/parse/scanForContent.d.ts +13 -0
- package/dist/next/parse/scanForContent.js +189 -0
- package/dist/react/config/createESBuildConfig.d.ts +2 -0
- package/dist/react/config/createESBuildConfig.js +134 -0
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.d.ts +1 -0
- package/dist/react/data-_gt/addGTIdentifierToSyntaxTree.js +92 -0
- package/dist/react/jsx/evaluateJsx.d.ts +17 -0
- package/dist/react/jsx/evaluateJsx.js +133 -0
- package/dist/react/jsx/trimJsxStringChildren.d.ts +7 -0
- package/dist/react/jsx/trimJsxStringChildren.js +97 -0
- package/dist/react/jsx/utils/parseAst.d.ts +30 -0
- package/dist/react/jsx/utils/parseAst.js +320 -0
- package/dist/react/jsx/utils/parseJsx.d.ts +13 -0
- package/dist/react/jsx/utils/parseJsx.js +236 -0
- package/dist/react/jsx/utils/parseStringFunction.d.ts +12 -0
- package/dist/react/jsx/utils/parseStringFunction.js +120 -0
- package/dist/react/jsx/wrapJsx.d.ts +51 -0
- package/dist/react/jsx/wrapJsx.js +407 -0
- package/dist/react/parse/createDictionaryUpdates.d.ts +5 -0
- package/dist/react/parse/createDictionaryUpdates.js +77 -0
- package/dist/react/parse/createInlineUpdates.d.ts +5 -0
- package/dist/react/parse/createInlineUpdates.js +141 -0
- package/dist/react/parse/index.d.ts +3 -0
- package/dist/react/parse/index.js +12 -0
- package/dist/react/parse/scanForContent.d.ts +13 -0
- package/dist/react/parse/scanForContent.js +200 -0
- package/dist/react/types.d.ts +13 -0
- package/dist/react/types.js +2 -0
- package/dist/react/utils/flattenDictionary.d.ts +10 -0
- package/dist/react/utils/flattenDictionary.js +38 -0
- package/dist/react/utils/getEntryAndMetadata.d.ts +5 -0
- package/dist/react/utils/getEntryAndMetadata.js +14 -0
- package/dist/react/utils/getVariableName.d.ts +2 -0
- package/dist/react/utils/getVariableName.js +20 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.js +2 -0
- package/package.json +9 -2
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { NodePath } from '@babel/traverse';
|
|
3
|
+
export declare function isHtmlElement(element: t.JSXOpeningElement): boolean;
|
|
4
|
+
export declare function isBodyElement(element: t.JSXOpeningElement): boolean;
|
|
5
|
+
export declare function hasGTProviderChild(element: t.JSXElement): boolean;
|
|
6
|
+
export declare function addDynamicLangAttribute(element: t.JSXOpeningElement): void;
|
|
7
|
+
export declare function makeParentFunctionAsync(path: NodePath): boolean;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.isHtmlElement = isHtmlElement;
|
|
37
|
+
exports.isBodyElement = isBodyElement;
|
|
38
|
+
exports.hasGTProviderChild = hasGTProviderChild;
|
|
39
|
+
exports.addDynamicLangAttribute = addDynamicLangAttribute;
|
|
40
|
+
exports.makeParentFunctionAsync = makeParentFunctionAsync;
|
|
41
|
+
const t = __importStar(require("@babel/types"));
|
|
42
|
+
// Helper function to check if is the <html> fragment
|
|
43
|
+
function isHtmlElement(element) {
|
|
44
|
+
return (t.isJSXIdentifier(element.name) &&
|
|
45
|
+
element.name.name.toLowerCase() === 'html');
|
|
46
|
+
}
|
|
47
|
+
// Helper function to check if is the <body> fragment
|
|
48
|
+
function isBodyElement(element) {
|
|
49
|
+
return (t.isJSXIdentifier(element.name) &&
|
|
50
|
+
element.name.name.toLowerCase() === 'body');
|
|
51
|
+
}
|
|
52
|
+
// Helper function to check if the <body> element has a <GTProvider> child
|
|
53
|
+
function hasGTProviderChild(element) {
|
|
54
|
+
return element.children.some((child) => t.isJSXElement(child) &&
|
|
55
|
+
t.isJSXIdentifier(child.openingElement.name) &&
|
|
56
|
+
child.openingElement.name.name === 'GTProvider');
|
|
57
|
+
}
|
|
58
|
+
function addDynamicLangAttribute(element) {
|
|
59
|
+
// Remove existing lang attribute if present
|
|
60
|
+
const langAttrIndex = element.attributes.findIndex((attr) => t.isJSXAttribute(attr) &&
|
|
61
|
+
t.isJSXIdentifier(attr.name) &&
|
|
62
|
+
attr.name.name === 'lang');
|
|
63
|
+
if (langAttrIndex !== -1) {
|
|
64
|
+
element.attributes.splice(langAttrIndex, 1);
|
|
65
|
+
}
|
|
66
|
+
// Add lang={await getLocale()} attribute
|
|
67
|
+
element.attributes.push(t.jsxAttribute(t.jsxIdentifier('lang'), t.jsxExpressionContainer(t.awaitExpression(t.callExpression(t.identifier('getLocale'), [])))));
|
|
68
|
+
}
|
|
69
|
+
function makeParentFunctionAsync(path) {
|
|
70
|
+
const functionParent = path.getFunctionParent();
|
|
71
|
+
if (!functionParent)
|
|
72
|
+
return false;
|
|
73
|
+
const node = functionParent.node;
|
|
74
|
+
if ((t.isFunctionDeclaration(node) ||
|
|
75
|
+
t.isFunctionExpression(node) ||
|
|
76
|
+
t.isArrowFunctionExpression(node)) &&
|
|
77
|
+
!node.async) {
|
|
78
|
+
node.async = true;
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.default = handleInitGT;
|
|
49
|
+
const fs_1 = __importDefault(require("fs"));
|
|
50
|
+
const parser_1 = require("@babel/parser");
|
|
51
|
+
const generator_1 = __importDefault(require("@babel/generator"));
|
|
52
|
+
const traverse_1 = __importDefault(require("@babel/traverse"));
|
|
53
|
+
const t = __importStar(require("@babel/types"));
|
|
54
|
+
function handleInitGT(filepath) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
const errors = [];
|
|
57
|
+
const warnings = [];
|
|
58
|
+
const filesUpdated = [];
|
|
59
|
+
const code = fs_1.default.readFileSync(filepath, 'utf8');
|
|
60
|
+
let ast;
|
|
61
|
+
try {
|
|
62
|
+
ast = (0, parser_1.parse)(code, {
|
|
63
|
+
sourceType: 'module',
|
|
64
|
+
plugins: ['jsx', 'typescript'],
|
|
65
|
+
tokens: true,
|
|
66
|
+
createParenthesizedExpressions: true,
|
|
67
|
+
});
|
|
68
|
+
const needsCJS = filepath.endsWith('.js');
|
|
69
|
+
// Check if withGTConfig or initGT is already imported/required
|
|
70
|
+
let hasGTConfig = false;
|
|
71
|
+
let hasInitGT = false;
|
|
72
|
+
(0, traverse_1.default)(ast, {
|
|
73
|
+
ImportDeclaration(path) {
|
|
74
|
+
if (path.node.source.value === 'gt-next/config') {
|
|
75
|
+
path.node.specifiers.forEach((spec) => {
|
|
76
|
+
if (t.isImportSpecifier(spec)) {
|
|
77
|
+
if (spec.local.name === 'withGTConfig')
|
|
78
|
+
hasGTConfig = true;
|
|
79
|
+
if (spec.local.name === 'initGT')
|
|
80
|
+
hasInitGT = true;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
VariableDeclaration(path) {
|
|
86
|
+
path.node.declarations.forEach((dec) => {
|
|
87
|
+
if (t.isVariableDeclarator(dec) &&
|
|
88
|
+
t.isCallExpression(dec.init) &&
|
|
89
|
+
t.isIdentifier(dec.init.callee, { name: 'require' }) &&
|
|
90
|
+
t.isStringLiteral(dec.init.arguments[0], {
|
|
91
|
+
value: 'gt-next/config',
|
|
92
|
+
})) {
|
|
93
|
+
if (t.isIdentifier(dec.id, { name: 'withGTConfig' }))
|
|
94
|
+
hasGTConfig = true;
|
|
95
|
+
if (t.isIdentifier(dec.id, { name: 'initGT' }))
|
|
96
|
+
hasInitGT = true;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
// Return early if either withGTConfig or initGT is already present
|
|
102
|
+
if (hasGTConfig || hasInitGT) {
|
|
103
|
+
return { errors, filesUpdated, warnings };
|
|
104
|
+
}
|
|
105
|
+
ast.program.body.unshift(needsCJS
|
|
106
|
+
? t.variableDeclaration('const', [
|
|
107
|
+
t.variableDeclarator(t.identifier('withGTConfig'), t.memberExpression(t.callExpression(t.identifier('require'), [
|
|
108
|
+
t.stringLiteral('gt-next/config'),
|
|
109
|
+
]), t.identifier('withGTConfig'))),
|
|
110
|
+
])
|
|
111
|
+
: t.importDeclaration([
|
|
112
|
+
t.importSpecifier(t.identifier('withGTConfig'), t.identifier('withGTConfig')),
|
|
113
|
+
], t.stringLiteral('gt-next/config')));
|
|
114
|
+
// Find and transform the default export
|
|
115
|
+
(0, traverse_1.default)(ast, {
|
|
116
|
+
ExportDefaultDeclaration(path) {
|
|
117
|
+
const oldExport = path.node.declaration;
|
|
118
|
+
let exportExpression;
|
|
119
|
+
if (t.isFunctionDeclaration(oldExport)) {
|
|
120
|
+
exportExpression = t.functionExpression(oldExport.id, oldExport.params, oldExport.body, oldExport.generator, oldExport.async);
|
|
121
|
+
}
|
|
122
|
+
else if (t.isClassDeclaration(oldExport)) {
|
|
123
|
+
exportExpression = t.classExpression(oldExport.id, oldExport.superClass, oldExport.body, oldExport.decorators);
|
|
124
|
+
}
|
|
125
|
+
else if (t.isTSDeclareFunction(oldExport)) {
|
|
126
|
+
// For TypeScript declare functions, create an empty function expression
|
|
127
|
+
// since declare functions don't have a runtime implementation
|
|
128
|
+
warnings.push(`Found TypeScript declare function in ${filepath}. Converting to empty function.`);
|
|
129
|
+
exportExpression = t.functionExpression(oldExport.id, oldExport.params, t.blockStatement([]), false, false);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
exportExpression = oldExport;
|
|
133
|
+
}
|
|
134
|
+
// Validate that we have a valid Next.js config export
|
|
135
|
+
if (!t.isObjectExpression(exportExpression) &&
|
|
136
|
+
!t.isFunctionExpression(exportExpression) &&
|
|
137
|
+
!t.isArrowFunctionExpression(exportExpression)) {
|
|
138
|
+
warnings.push(`Unexpected export type in ${filepath}. Next.js config should export an object or a function returning an object.`);
|
|
139
|
+
}
|
|
140
|
+
path.node.declaration = t.callExpression(t.identifier('withGTConfig'), [
|
|
141
|
+
exportExpression,
|
|
142
|
+
t.objectExpression([]),
|
|
143
|
+
]);
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
// Generate the modified code
|
|
147
|
+
const output = (0, generator_1.default)(ast, {
|
|
148
|
+
retainLines: true,
|
|
149
|
+
retainFunctionParens: true,
|
|
150
|
+
comments: true,
|
|
151
|
+
compact: 'auto',
|
|
152
|
+
}, code);
|
|
153
|
+
// Post-process the output to fix import spacing
|
|
154
|
+
let processedCode = output.code;
|
|
155
|
+
// Add newline after the comment only
|
|
156
|
+
processedCode = processedCode.replace(/((?:import\s*{\s*withGTConfig\s*}\s*from|const\s*{\s*withGTConfig\s*}\s*=\s*require)\s*['"]gt-next\/config['"];?)/, '$1\n');
|
|
157
|
+
// Write the modified code back to the file
|
|
158
|
+
fs_1.default.writeFileSync(filepath, processedCode);
|
|
159
|
+
filesUpdated.push(filepath);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
console.error(`Error parsing file ${filepath}:`, error);
|
|
163
|
+
errors.push(`Failed to parse ${filepath}: ${error}`);
|
|
164
|
+
}
|
|
165
|
+
return { errors, filesUpdated, warnings };
|
|
166
|
+
});
|
|
167
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as scanForContent } from './scanForContent';
|
|
2
|
+
export { default as handleInitGT } from './handleInitGT';
|
|
3
|
+
export { default as createDictionaryUpdates } from '../../react/parse/createDictionaryUpdates';
|
|
4
|
+
export { default as createInlineUpdates } from '../../react/parse/createInlineUpdates';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createInlineUpdates = exports.createDictionaryUpdates = exports.handleInitGT = exports.scanForContent = void 0;
|
|
7
|
+
var scanForContent_1 = require("./scanForContent");
|
|
8
|
+
Object.defineProperty(exports, "scanForContent", { enumerable: true, get: function () { return __importDefault(scanForContent_1).default; } });
|
|
9
|
+
var handleInitGT_1 = require("./handleInitGT");
|
|
10
|
+
Object.defineProperty(exports, "handleInitGT", { enumerable: true, get: function () { return __importDefault(handleInitGT_1).default; } });
|
|
11
|
+
var createDictionaryUpdates_1 = require("../../react/parse/createDictionaryUpdates");
|
|
12
|
+
Object.defineProperty(exports, "createDictionaryUpdates", { enumerable: true, get: function () { return __importDefault(createDictionaryUpdates_1).default; } });
|
|
13
|
+
var createInlineUpdates_1 = require("../../react/parse/createInlineUpdates");
|
|
14
|
+
Object.defineProperty(exports, "createInlineUpdates", { enumerable: true, get: function () { return __importDefault(createInlineUpdates_1).default; } });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SupportedFrameworks, WrapOptions } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Wraps all JSX elements in the src directory with a <T> tag, with unique ids.
|
|
4
|
+
* - Ignores pure strings
|
|
5
|
+
*
|
|
6
|
+
* @param options - The options object
|
|
7
|
+
* @returns An object containing the updates and errors
|
|
8
|
+
*/
|
|
9
|
+
export default function scanForContent(options: WrapOptions, pkg: 'gt-next' | 'gt-react', framework: SupportedFrameworks): Promise<{
|
|
10
|
+
errors: string[];
|
|
11
|
+
filesUpdated: string[];
|
|
12
|
+
warnings: string[];
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.default = scanForContent;
|
|
49
|
+
const fs_1 = __importDefault(require("fs"));
|
|
50
|
+
const t = __importStar(require("@babel/types"));
|
|
51
|
+
const parser_1 = require("@babel/parser");
|
|
52
|
+
const traverse_1 = __importDefault(require("@babel/traverse"));
|
|
53
|
+
const generator_1 = __importDefault(require("@babel/generator"));
|
|
54
|
+
const findJsxFilepath_1 = require("../../fs/findJsxFilepath");
|
|
55
|
+
const evaluateJsx_1 = require("../../react/jsx/evaluateJsx");
|
|
56
|
+
const wrapJsx_1 = require("../../react/jsx/wrapJsx");
|
|
57
|
+
const findFilepath_1 = require("../../fs/findFilepath");
|
|
58
|
+
const utils_1 = require("../jsx/utils");
|
|
59
|
+
const parseAst_1 = require("../../react/jsx/utils/parseAst");
|
|
60
|
+
const IMPORT_MAP = {
|
|
61
|
+
T: { name: 'T', source: 'gt-next' },
|
|
62
|
+
Var: { name: 'Var', source: 'gt-next' },
|
|
63
|
+
GTT: { name: 'T', source: 'gt-next' },
|
|
64
|
+
GTVar: { name: 'Var', source: 'gt-next' },
|
|
65
|
+
GTProvider: { name: 'GTProvider', source: 'gt-next' },
|
|
66
|
+
getLocale: { name: 'getLocale', source: 'gt-next/server' },
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Wraps all JSX elements in the src directory with a <T> tag, with unique ids.
|
|
70
|
+
* - Ignores pure strings
|
|
71
|
+
*
|
|
72
|
+
* @param options - The options object
|
|
73
|
+
* @returns An object containing the updates and errors
|
|
74
|
+
*/
|
|
75
|
+
function scanForContent(options, pkg, framework) {
|
|
76
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
const errors = [];
|
|
78
|
+
const warnings = [];
|
|
79
|
+
const srcDirectory = options.src || ['./'];
|
|
80
|
+
const files = srcDirectory.flatMap((dir) => (0, findJsxFilepath_1.getFiles)(dir));
|
|
81
|
+
const filesUpdated = [];
|
|
82
|
+
for (const file of files) {
|
|
83
|
+
const code = fs_1.default.readFileSync(file, 'utf8');
|
|
84
|
+
// Create relative path from src directory and remove extension
|
|
85
|
+
const relativePath = (0, findFilepath_1.getRelativePath)(file, srcDirectory[0]);
|
|
86
|
+
let ast;
|
|
87
|
+
try {
|
|
88
|
+
ast = (0, parser_1.parse)(code, {
|
|
89
|
+
sourceType: 'module',
|
|
90
|
+
plugins: ['jsx', 'typescript'],
|
|
91
|
+
tokens: true,
|
|
92
|
+
createParenthesizedExpressions: true,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
console.error(`Error parsing file ${file}:`, error);
|
|
97
|
+
errors.push(`Failed to parse ${file}: ${error}`);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
let modified = false;
|
|
101
|
+
let usedImports = [];
|
|
102
|
+
let { importAlias, initialImports } = (0, parseAst_1.generateImportMap)(ast, pkg);
|
|
103
|
+
// If the file already has a T import, skip processing it
|
|
104
|
+
if (initialImports.includes(IMPORT_MAP.T.name)) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
let globalId = 0;
|
|
108
|
+
(0, traverse_1.default)(ast, {
|
|
109
|
+
JSXElement(path) {
|
|
110
|
+
var _a;
|
|
111
|
+
if (pkg === 'gt-next' &&
|
|
112
|
+
options.addGTProvider &&
|
|
113
|
+
(0, utils_1.isHtmlElement)(path.node.openingElement)) {
|
|
114
|
+
// Find the body element in the HTML children
|
|
115
|
+
const bodyElement = path.node.children.find((child) => t.isJSXElement(child) && (0, utils_1.isBodyElement)(child.openingElement));
|
|
116
|
+
if (!bodyElement) {
|
|
117
|
+
warnings.push(`File ${file} has a <html> tag without a <body> tag. Skipping GTProvider insertion.`);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// Skip if body already has GTProvider
|
|
121
|
+
if ((0, utils_1.hasGTProviderChild)(bodyElement)) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// Handle lang attribute for html tag
|
|
125
|
+
const langAttr = path.node.openingElement.attributes.find((attr) => t.isJSXAttribute(attr) &&
|
|
126
|
+
t.isJSXIdentifier(attr.name) &&
|
|
127
|
+
t.isStringLiteral(attr.value) &&
|
|
128
|
+
attr.name.name === 'lang');
|
|
129
|
+
if (langAttr) {
|
|
130
|
+
(0, utils_1.makeParentFunctionAsync)(path);
|
|
131
|
+
(0, utils_1.addDynamicLangAttribute)(path.node.openingElement);
|
|
132
|
+
usedImports.push('getLocale');
|
|
133
|
+
}
|
|
134
|
+
// Wrap body children with GTProvider
|
|
135
|
+
const bodyChildren = bodyElement.children;
|
|
136
|
+
const gtProviderElement = t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier('GTProvider'), [], false), t.jsxClosingElement(t.jsxIdentifier('GTProvider')), bodyChildren, false);
|
|
137
|
+
bodyElement.children = [gtProviderElement];
|
|
138
|
+
usedImports.push('GTProvider');
|
|
139
|
+
modified = true;
|
|
140
|
+
path.skip();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Check if this JSX element has any JSX element ancestors
|
|
144
|
+
let currentPath = path;
|
|
145
|
+
if (t.isJSXElement((_a = currentPath.parentPath) === null || _a === void 0 ? void 0 : _a.node)) {
|
|
146
|
+
// If we found a JSX parent, skip processing this node
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// At this point, we're only processing top-level JSX elements
|
|
150
|
+
const opts = Object.assign(Object.assign({}, importAlias), { idPrefix: relativePath, idCount: globalId, usedImports, modified: false, createIds: !options.disableIds, warnings,
|
|
151
|
+
file });
|
|
152
|
+
const wrapped = (0, wrapJsx_1.handleJsxElement)(path.node, opts, evaluateJsx_1.isMeaningful);
|
|
153
|
+
path.replaceWith(wrapped.node);
|
|
154
|
+
// Update global counters
|
|
155
|
+
modified = modified || opts.modified;
|
|
156
|
+
globalId = opts.idCount;
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
if (!modified)
|
|
160
|
+
continue;
|
|
161
|
+
let needsImport = usedImports.filter((imp) => !initialImports.includes(imp));
|
|
162
|
+
if (needsImport.length > 0) {
|
|
163
|
+
(0, parseAst_1.createImports)(ast, needsImport, IMPORT_MAP);
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const output = (0, generator_1.default)(ast, {
|
|
167
|
+
retainLines: true,
|
|
168
|
+
retainFunctionParens: true,
|
|
169
|
+
comments: true,
|
|
170
|
+
compact: 'auto',
|
|
171
|
+
}, code);
|
|
172
|
+
// Post-process the output to fix import spacing
|
|
173
|
+
let processedCode = output.code;
|
|
174
|
+
if (needsImport.length > 0) {
|
|
175
|
+
// Add newline after the comment only
|
|
176
|
+
processedCode = processedCode.replace(/((?:import\s*{\s*(?:T|GTT|Var|GTVar|GTProvider|getLocale)(?:\s*,\s*(?:T|GTT|Var|GTVar|GTProvider|getLocale))*\s*}\s*from|const\s*{\s*(?:T|GTT|Var|GTVar|GTProvider|getLocale)(?:\s*,\s*(?:T|GTT|Var|GTVar|GTProvider|getLocale))*\s*}\s*=\s*require)\s*['"]gt-(?:next|react)(?:\/server)?['"];?)/, '\n$1\n');
|
|
177
|
+
}
|
|
178
|
+
// Write the modified code back to the file
|
|
179
|
+
fs_1.default.writeFileSync(file, processedCode);
|
|
180
|
+
filesUpdated.push(file);
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.error(`Error writing file ${file}:`, error);
|
|
184
|
+
errors.push(`Failed to write ${file}: ${error}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return { errors, filesUpdated, warnings };
|
|
188
|
+
});
|
|
189
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.default = createESBuildConfig;
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const console_1 = require("../../console/console");
|
|
19
|
+
function createESBuildConfig(config = {}) {
|
|
20
|
+
const esbuildOptions = {
|
|
21
|
+
bundle: true,
|
|
22
|
+
format: 'cjs',
|
|
23
|
+
platform: 'node',
|
|
24
|
+
target: 'es2021',
|
|
25
|
+
loader: {
|
|
26
|
+
'.js': 'jsx',
|
|
27
|
+
'.ts': 'ts',
|
|
28
|
+
'.css': 'css', // Add CSS loader
|
|
29
|
+
},
|
|
30
|
+
sourcemap: 'inline',
|
|
31
|
+
external: ['server-only'],
|
|
32
|
+
define: {
|
|
33
|
+
React: 'global.React',
|
|
34
|
+
},
|
|
35
|
+
plugins: [],
|
|
36
|
+
};
|
|
37
|
+
// Add the custom plugin to handle 'server-only' imports
|
|
38
|
+
esbuildOptions.plugins.push({
|
|
39
|
+
name: 'ignore-server-only',
|
|
40
|
+
setup(build) {
|
|
41
|
+
build.onResolve({ filter: /^server-only$/ }, () => {
|
|
42
|
+
return {
|
|
43
|
+
path: 'server-only',
|
|
44
|
+
namespace: 'ignore-server-only',
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
build.onLoad({ filter: /^server-only$/, namespace: 'ignore-server-only' }, () => {
|
|
48
|
+
return {
|
|
49
|
+
contents: 'module.exports = {};',
|
|
50
|
+
loader: 'js',
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
// Add a plugin to handle CSS imports
|
|
56
|
+
esbuildOptions.plugins.push({
|
|
57
|
+
name: 'css-module',
|
|
58
|
+
setup(build) {
|
|
59
|
+
build.onResolve({ filter: /\.css$/ }, (args) => {
|
|
60
|
+
return {
|
|
61
|
+
path: path_1.default.resolve(args.resolveDir, args.path),
|
|
62
|
+
namespace: 'css-module',
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
build.onLoad({ filter: /\.css$/, namespace: 'css-module' }, (args) => __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const css = yield fs_1.default.promises.readFile(args.path, 'utf8');
|
|
67
|
+
const contents = `
|
|
68
|
+
const style = document.createElement('style');
|
|
69
|
+
style.textContent = ${JSON.stringify(css)};
|
|
70
|
+
document.head.appendChild(style);
|
|
71
|
+
`;
|
|
72
|
+
return { contents, loader: 'js' };
|
|
73
|
+
}));
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
if (config.compilerOptions) {
|
|
77
|
+
if (config.compilerOptions.paths) {
|
|
78
|
+
const aliases = {};
|
|
79
|
+
const resolvedPaths = [];
|
|
80
|
+
for (const [key, value] of Object.entries(config.compilerOptions.paths)) {
|
|
81
|
+
if (Array.isArray(value) && typeof value[0] === 'string') {
|
|
82
|
+
const resolvedPath = path_1.default.resolve(process.cwd(), value[0].replace('/*', ''));
|
|
83
|
+
aliases[key.replace('/*', '')] = resolvedPath;
|
|
84
|
+
resolvedPaths.push([key, resolvedPath]);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (resolvedPaths.length) {
|
|
88
|
+
(0, console_1.displayResolvedPaths)(resolvedPaths);
|
|
89
|
+
}
|
|
90
|
+
esbuildOptions.plugins = esbuildOptions.plugins || [];
|
|
91
|
+
esbuildOptions.plugins.push({
|
|
92
|
+
name: 'alias',
|
|
93
|
+
setup(build) {
|
|
94
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
95
|
+
for (const [aliasKey, aliasPath] of Object.entries(aliases)) {
|
|
96
|
+
if (args.path.startsWith(`${aliasKey}/`)) {
|
|
97
|
+
const resolvedPath = path_1.default.resolve(aliasPath, args.path.slice(aliasKey.length + 1));
|
|
98
|
+
const extensions = ['.js', '.ts', '.css']; // Add .css to extensions
|
|
99
|
+
function resolveWithExtensions(basePath) {
|
|
100
|
+
for (const ext of extensions) {
|
|
101
|
+
const fullPath = `${basePath}${ext}`;
|
|
102
|
+
try {
|
|
103
|
+
const realPath = fs_1.default.realpathSync(fullPath);
|
|
104
|
+
return realPath;
|
|
105
|
+
}
|
|
106
|
+
catch (_) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const realPath = fs_1.default.realpathSync(resolvedPath);
|
|
114
|
+
return { path: realPath };
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
const hasExtension = extensions.some((ext) => resolvedPath.endsWith(ext));
|
|
118
|
+
if (!hasExtension) {
|
|
119
|
+
const resolvedWithExt = resolveWithExtensions(resolvedPath);
|
|
120
|
+
if (resolvedWithExt) {
|
|
121
|
+
return { path: resolvedWithExt };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
throw new Error(`Unable to resolve path: ${resolvedPath}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return esbuildOptions;
|
|
134
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function addGTIdentifierToSyntaxTree(tree: any, startingIndex?: number): any;
|