@intlayer/chokidar 9.0.0-canary.4 → 9.0.0-canary.5
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/assets/initConfig/templates/cjs.txt +7 -0
- package/dist/assets/initConfig/templates/json.txt +7 -1
- package/dist/assets/initConfig/templates/mjs.txt +7 -0
- package/dist/assets/initConfig/templates/ts.txt +7 -0
- package/dist/assets/installSkills/skills/cli.md +0 -1
- package/dist/cjs/cli.cjs +9 -0
- package/dist/cjs/init/cms.cjs +140 -0
- package/dist/cjs/init/cms.cjs.map +1 -0
- package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs +1 -1
- package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs.map +1 -1
- package/dist/cjs/init/index.cjs +14 -4
- package/dist/cjs/init/index.cjs.map +1 -1
- package/dist/cjs/init/utils/configManipulation.cjs +101 -10
- package/dist/cjs/init/utils/configManipulation.cjs.map +1 -1
- package/dist/cjs/init/utils/index.cjs +6 -1
- package/dist/cjs/init/utils/nextCompilerBabel.cjs +119 -0
- package/dist/cjs/init/utils/nextCompilerBabel.cjs.map +1 -0
- package/dist/esm/cli.mjs +4 -1
- package/dist/esm/init/cms.mjs +131 -0
- package/dist/esm/init/cms.mjs.map +1 -0
- package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs +1 -1
- package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs.map +1 -1
- package/dist/esm/init/index.mjs +14 -4
- package/dist/esm/init/index.mjs.map +1 -1
- package/dist/esm/init/utils/configManipulation.mjs +100 -11
- package/dist/esm/init/utils/configManipulation.mjs.map +1 -1
- package/dist/esm/init/utils/index.mjs +3 -2
- package/dist/esm/init/utils/nextCompilerBabel.mjs +115 -0
- package/dist/esm/init/utils/nextCompilerBabel.mjs.map +1 -0
- package/dist/types/cli.d.ts +5 -1
- package/dist/types/init/cms.d.ts +51 -0
- package/dist/types/init/cms.d.ts.map +1 -0
- package/dist/types/init/frameworkSetup/nextAppRouter/transforms.d.ts.map +1 -1
- package/dist/types/init/index.d.ts +7 -0
- package/dist/types/init/index.d.ts.map +1 -1
- package/dist/types/init/utils/configManipulation.d.ts +21 -1
- package/dist/types/init/utils/configManipulation.d.ts.map +1 -1
- package/dist/types/init/utils/index.d.ts +3 -2
- package/dist/types/init/utils/nextCompilerBabel.d.ts +53 -0
- package/dist/types/init/utils/nextCompilerBabel.d.ts.map +1 -0
- package/package.json +8 -8
|
@@ -24,6 +24,13 @@ const config = {
|
|
|
24
24
|
* Default: "prefix-no-default"
|
|
25
25
|
*/
|
|
26
26
|
mode: 'prefix-no-default',
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Enables the Intlayer locale-routing proxy (middleware).
|
|
30
|
+
* Handles locale detection, redirects and rewrites in dev, preview and SSR.
|
|
31
|
+
* Default: true
|
|
32
|
+
*/
|
|
33
|
+
enableProxy: true,
|
|
27
34
|
},
|
|
28
35
|
editor: {
|
|
29
36
|
/**
|
|
@@ -19,7 +19,13 @@
|
|
|
19
19
|
* - "search-params": Use search params to define the locale (e.g., /dashboard/?locale=en, /dashboard/?locale=fr)
|
|
20
20
|
* Default: "prefix-no-default"
|
|
21
21
|
*/
|
|
22
|
-
"mode": "prefix-no-default"
|
|
22
|
+
"mode": "prefix-no-default",
|
|
23
|
+
/**
|
|
24
|
+
* Enables the Intlayer locale-routing proxy (middleware).
|
|
25
|
+
* Handles locale detection, redirects and rewrites in dev, preview and SSR.
|
|
26
|
+
* Default: true
|
|
27
|
+
*/
|
|
28
|
+
"enableProxy": true
|
|
23
29
|
},
|
|
24
30
|
"editor": {
|
|
25
31
|
/**
|
|
@@ -24,6 +24,13 @@ const config = {
|
|
|
24
24
|
* Default: "prefix-no-default"
|
|
25
25
|
*/
|
|
26
26
|
mode: 'prefix-no-default',
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Enables the Intlayer locale-routing proxy (middleware).
|
|
30
|
+
* Handles locale detection, redirects and rewrites in dev, preview and SSR.
|
|
31
|
+
* Default: true
|
|
32
|
+
*/
|
|
33
|
+
enableProxy: true,
|
|
27
34
|
},
|
|
28
35
|
editor: {
|
|
29
36
|
/**
|
|
@@ -23,6 +23,13 @@ const config: IntlayerConfig = {
|
|
|
23
23
|
* Default: "prefix-no-default"
|
|
24
24
|
*/
|
|
25
25
|
mode: 'prefix-no-default',
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Enables the Intlayer locale-routing proxy (middleware).
|
|
29
|
+
* Handles locale detection, redirects and rewrites in dev, preview and SSR.
|
|
30
|
+
* Default: true
|
|
31
|
+
*/
|
|
32
|
+
enableProxy: true,
|
|
26
33
|
},
|
|
27
34
|
editor: {
|
|
28
35
|
/**
|
|
@@ -40,7 +40,6 @@ npm install intlayer-cli
|
|
|
40
40
|
|
|
41
41
|
- [Build](https://intlayer.org/doc/concept/cli/build.md)
|
|
42
42
|
- [CI](https://intlayer.org/doc/concept/cli.md)
|
|
43
|
-
- [CLI Overview](https://intlayer.org/doc/concept/cli/export.md)
|
|
44
43
|
- [Configuration](https://intlayer.org/doc/concept/cli/configuration.md)
|
|
45
44
|
- [Debug](https://intlayer.org/doc/concept/cli/debug.md)
|
|
46
45
|
- [Doc Review](https://intlayer.org/doc/concept/cli/doc-review.md)
|
package/dist/cjs/cli.cjs
CHANGED
|
@@ -9,23 +9,30 @@ const require_detectFormatCommand = require('./detectFormatCommand.cjs');
|
|
|
9
9
|
const require_getContentDeclarationFileTemplate_getContentDeclarationFileTemplate = require('./getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.cjs');
|
|
10
10
|
const require_writeContentDeclaration_writeJSFile = require('./writeContentDeclaration/writeJSFile.cjs');
|
|
11
11
|
const require_writeContentDeclaration_writeContentDeclaration = require('./writeContentDeclaration/writeContentDeclaration.cjs');
|
|
12
|
+
const require_init_cms = require('./init/cms.cjs');
|
|
13
|
+
const require_init_utils_packageManager = require('./init/utils/packageManager.cjs');
|
|
14
|
+
const require_init_utils_nextCompilerBabel = require('./init/utils/nextCompilerBabel.cjs');
|
|
12
15
|
const require_init_index = require('./init/index.cjs');
|
|
13
16
|
const require_installSkills_index = require('./installSkills/index.cjs');
|
|
14
17
|
const require_installMCP_installMCP = require('./installMCP/installMCP.cjs');
|
|
15
18
|
const require_listGitFiles = require('./listGitFiles.cjs');
|
|
16
19
|
const require_logConfigDetails = require('./logConfigDetails.cjs');
|
|
17
20
|
|
|
21
|
+
exports.NEXT_INTLAYER_BABEL_CONFIG_CONTENT = require_init_utils_nextCompilerBabel.NEXT_INTLAYER_BABEL_CONFIG_CONTENT;
|
|
18
22
|
exports.PLATFORMS = require_installSkills_index.PLATFORMS;
|
|
19
23
|
exports.PLATFORMS_METADATA = require_installSkills_index.PLATFORMS_METADATA;
|
|
20
24
|
exports.SKILLS = require_installSkills_index.SKILLS;
|
|
21
25
|
exports.SKILLS_METADATA = require_installSkills_index.SKILLS_METADATA;
|
|
22
26
|
exports.detectExportedComponentName = require_writeContentDeclaration_detectExportedComponentName.detectExportedComponentName;
|
|
23
27
|
exports.detectFormatCommand = require_detectFormatCommand.detectFormatCommand;
|
|
28
|
+
exports.detectPackageManager = require_init_utils_packageManager.detectPackageManager;
|
|
29
|
+
exports.enableEditorInConfig = require_init_cms.enableEditorInConfig;
|
|
24
30
|
exports.getContentDeclarationFileTemplate = require_getContentDeclarationFileTemplate_getContentDeclarationFileTemplate.getContentDeclarationFileTemplate;
|
|
25
31
|
exports.getInitialSkills = require_installSkills_index.getInitialSkills;
|
|
26
32
|
exports.initIntlayer = require_init_index.initIntlayer;
|
|
27
33
|
exports.installLSP = require_installLSP.installLSP;
|
|
28
34
|
exports.installMCP = require_installMCP_installMCP.installMCP;
|
|
35
|
+
exports.installPackages = require_init_utils_packageManager.installPackages;
|
|
29
36
|
exports.installSkills = require_installSkills_index.installSkills;
|
|
30
37
|
exports.listDictionaries = require_listDictionariesPath.listDictionaries;
|
|
31
38
|
exports.listDictionariesWithStats = require_listDictionariesPath.listDictionariesWithStats;
|
|
@@ -34,6 +41,8 @@ exports.listGitLines = require_listGitFiles.listGitLines;
|
|
|
34
41
|
exports.listProjects = require_listProjects.listProjects;
|
|
35
42
|
exports.logConfigDetails = require_logConfigDetails.logConfigDetails;
|
|
36
43
|
exports.prepareIntlayer = require_prepareIntlayer.prepareIntlayer;
|
|
44
|
+
exports.setupCmsCredentials = require_init_cms.setupCmsCredentials;
|
|
37
45
|
exports.transformJSFile = require_writeContentDeclaration_transformJSFile.transformJSFile;
|
|
46
|
+
exports.writeCmsCredentialsToEnv = require_init_cms.writeCmsCredentialsToEnv;
|
|
38
47
|
exports.writeContentDeclaration = require_writeContentDeclaration_writeContentDeclaration.writeContentDeclaration;
|
|
39
48
|
exports.writeJSFile = require_writeContentDeclaration_writeJSFile.writeJSFile;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_init_utils_configManipulation = require('./utils/configManipulation.cjs');
|
|
4
|
+
const require_init_utils_fileSystem = require('./utils/fileSystem.cjs');
|
|
5
|
+
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
6
|
+
let fast_glob = require("fast-glob");
|
|
7
|
+
fast_glob = require_runtime.__toESM(fast_glob);
|
|
8
|
+
let _intlayer_config_colors = require("@intlayer/config/colors");
|
|
9
|
+
_intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
|
|
10
|
+
|
|
11
|
+
//#region src/init/cms.ts
|
|
12
|
+
/**
|
|
13
|
+
* Intlayer configuration file candidates, ordered by the precedence used when
|
|
14
|
+
* resolving which file to mutate.
|
|
15
|
+
*/
|
|
16
|
+
const INTLAYER_CONFIG_FILE_CANDIDATES = [
|
|
17
|
+
"intlayer.config.ts",
|
|
18
|
+
"intlayer.config.mjs",
|
|
19
|
+
"intlayer.config.js",
|
|
20
|
+
"intlayer.config.cjs",
|
|
21
|
+
"intlayer.config.json"
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* Environment files searched (most-preferred first) when persisting the CMS
|
|
25
|
+
* credentials. The first existing match is reused; otherwise a `.env` file is
|
|
26
|
+
* created at the project root.
|
|
27
|
+
*/
|
|
28
|
+
const ENV_FILE_CANDIDATES = [
|
|
29
|
+
".env",
|
|
30
|
+
".env.local",
|
|
31
|
+
".env.development"
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Resolves the first existing Intlayer configuration file at the project root,
|
|
35
|
+
* or `undefined` when none is present.
|
|
36
|
+
*/
|
|
37
|
+
const findIntlayerConfigFile = async (rootDir) => {
|
|
38
|
+
for (const candidate of INTLAYER_CONFIG_FILE_CANDIDATES) if (await require_init_utils_fileSystem.exists(rootDir, candidate)) return candidate;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Locates the environment file the CMS credentials should be written to. Uses
|
|
42
|
+
* `fast-glob` to detect an existing dotenv file at the project root, preferring
|
|
43
|
+
* a plain `.env`; falls back to `.env` (to be created) when none exist.
|
|
44
|
+
*/
|
|
45
|
+
const findEnvFile = async (rootDir) => {
|
|
46
|
+
const matches = await (0, fast_glob.default)([...ENV_FILE_CANDIDATES], {
|
|
47
|
+
cwd: rootDir,
|
|
48
|
+
dot: true,
|
|
49
|
+
deep: 1,
|
|
50
|
+
onlyFiles: true
|
|
51
|
+
});
|
|
52
|
+
return ENV_FILE_CANDIDATES.find((candidate) => matches.includes(candidate)) ?? ".env";
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Inserts or updates a `KEY=value` line in dotenv file content. An existing
|
|
56
|
+
* assignment of the same key is replaced in place; otherwise the line is
|
|
57
|
+
* appended with a trailing newline.
|
|
58
|
+
*/
|
|
59
|
+
const upsertEnvVariable = (content, key, value) => {
|
|
60
|
+
const line = `${key}=${value}`;
|
|
61
|
+
const keyMatcher = new RegExp(`^${key}=.*$`, "m");
|
|
62
|
+
if (keyMatcher.test(content)) return content.replace(keyMatcher, line);
|
|
63
|
+
return `${content}${content.length > 0 && !content.endsWith("\n") ? "\n" : ""}${line}\n`;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Persists the CMS access-key credentials to the project's environment file as
|
|
67
|
+
* `INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET`. The target file is detected
|
|
68
|
+
* with {@link findEnvFile} and created when missing. Returns the relative path
|
|
69
|
+
* of the file that was written.
|
|
70
|
+
*/
|
|
71
|
+
const writeCmsCredentialsToEnv = async (rootDir, { clientId, clientSecret }) => {
|
|
72
|
+
const envFile = await findEnvFile(rootDir);
|
|
73
|
+
let content = "";
|
|
74
|
+
if (await require_init_utils_fileSystem.exists(rootDir, envFile)) content = await require_init_utils_fileSystem.readFileFromRoot(rootDir, envFile);
|
|
75
|
+
let updatedContent = content;
|
|
76
|
+
updatedContent = upsertEnvVariable(updatedContent, "INTLAYER_CLIENT_ID", clientId);
|
|
77
|
+
updatedContent = upsertEnvVariable(updatedContent, "INTLAYER_CLIENT_SECRET", clientSecret);
|
|
78
|
+
await require_init_utils_fileSystem.writeFileToRoot(rootDir, envFile, updatedContent);
|
|
79
|
+
(0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Saved Intlayer CMS credentials to ${(0, _intlayer_config_logger.colorizePath)(envFile)} (${(0, _intlayer_config_logger.colorize)("INTLAYER_CLIENT_ID", _intlayer_config_colors.GREY_LIGHT)}, ${(0, _intlayer_config_logger.colorize)("INTLAYER_CLIENT_SECRET", _intlayer_config_colors.GREY_LIGHT)})`);
|
|
80
|
+
return envFile;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Enables the Intlayer visual editor in the project's configuration file:
|
|
84
|
+
* flips `editor.enabled` to `true` and wires `clientId` / `clientSecret` to the
|
|
85
|
+
* matching environment variables. JSON configs cannot reference `process.env`,
|
|
86
|
+
* so they are skipped with a warning. Returns the config file that was updated,
|
|
87
|
+
* or `undefined` when no editable config was found.
|
|
88
|
+
*/
|
|
89
|
+
const enableEditorInConfig = async (rootDir) => {
|
|
90
|
+
const configFile = await findIntlayerConfigFile(rootDir);
|
|
91
|
+
if (!configFile) {
|
|
92
|
+
(0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} Could not find an Intlayer configuration file to enable the editor.`, { level: "warn" });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (configFile.split(".").pop() === "json") {
|
|
96
|
+
(0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} ${(0, _intlayer_config_logger.colorizePath)(configFile)} is a JSON config and cannot reference environment variables. Enable the editor and set clientId/clientSecret manually.`, { level: "warn" });
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const content = await require_init_utils_fileSystem.readFileFromRoot(rootDir, configFile);
|
|
100
|
+
const updatedContent = require_init_utils_configManipulation.enableIntlayerEditorConfig(content);
|
|
101
|
+
if (updatedContent !== content) {
|
|
102
|
+
await require_init_utils_fileSystem.writeFileToRoot(rootDir, configFile, updatedContent);
|
|
103
|
+
(0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Enabled the Intlayer editor in ${(0, _intlayer_config_logger.colorizePath)(configFile)}`);
|
|
104
|
+
} else (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} ${(0, _intlayer_config_logger.colorizePath)(configFile)} already has the Intlayer editor enabled`);
|
|
105
|
+
return configFile;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Sets `routing.mode` in the project's Intlayer configuration file. Returns the
|
|
109
|
+
* config file that was updated, or `undefined` when none was found.
|
|
110
|
+
*/
|
|
111
|
+
const setRoutingModeInConfig = async (rootDir, mode) => {
|
|
112
|
+
const configFile = await findIntlayerConfigFile(rootDir);
|
|
113
|
+
if (!configFile) return void 0;
|
|
114
|
+
const extension = configFile.split(".").pop();
|
|
115
|
+
const content = await require_init_utils_fileSystem.readFileFromRoot(rootDir, configFile);
|
|
116
|
+
const updatedContent = require_init_utils_configManipulation.setIntlayerConfigRoutingMode(content, extension, mode);
|
|
117
|
+
if (updatedContent !== content) {
|
|
118
|
+
await require_init_utils_fileSystem.writeFileToRoot(rootDir, configFile, updatedContent);
|
|
119
|
+
(0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Set ${(0, _intlayer_config_logger.colorize)(`routing.mode = '${mode}'`, _intlayer_config_colors.GREY_LIGHT)} in ${(0, _intlayer_config_logger.colorizePath)(configFile)}`);
|
|
120
|
+
}
|
|
121
|
+
return configFile;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Completes the CMS setup once credentials are received from the login flow:
|
|
125
|
+
* writes them to the environment file and enables the editor in the Intlayer
|
|
126
|
+
* configuration file.
|
|
127
|
+
*/
|
|
128
|
+
const setupCmsCredentials = async (rootDir, credentials) => {
|
|
129
|
+
await writeCmsCredentialsToEnv(rootDir, credentials);
|
|
130
|
+
await enableEditorInConfig(rootDir);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
//#endregion
|
|
134
|
+
exports.INTLAYER_CONFIG_FILE_CANDIDATES = INTLAYER_CONFIG_FILE_CANDIDATES;
|
|
135
|
+
exports.enableEditorInConfig = enableEditorInConfig;
|
|
136
|
+
exports.findEnvFile = findEnvFile;
|
|
137
|
+
exports.setRoutingModeInConfig = setRoutingModeInConfig;
|
|
138
|
+
exports.setupCmsCredentials = setupCmsCredentials;
|
|
139
|
+
exports.writeCmsCredentialsToEnv = writeCmsCredentialsToEnv;
|
|
140
|
+
//# sourceMappingURL=cms.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cms.cjs","names":["exists","readFileFromRoot","writeFileToRoot","v","ANSIColors","x","enableIntlayerEditorConfig","setIntlayerConfigRoutingMode"],"sources":["../../../src/init/cms.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, logger, v, x } from '@intlayer/config/logger';\nimport fg from 'fast-glob';\nimport {\n enableIntlayerEditorConfig,\n type RoutingMode,\n setIntlayerConfigRoutingMode,\n} from './utils/configManipulation';\nimport { exists, readFileFromRoot, writeFileToRoot } from './utils/fileSystem';\n\n/**\n * Intlayer configuration file candidates, ordered by the precedence used when\n * resolving which file to mutate.\n */\nexport const INTLAYER_CONFIG_FILE_CANDIDATES = [\n 'intlayer.config.ts',\n 'intlayer.config.mjs',\n 'intlayer.config.js',\n 'intlayer.config.cjs',\n 'intlayer.config.json',\n] as const;\n\n/**\n * Environment files searched (most-preferred first) when persisting the CMS\n * credentials. The first existing match is reused; otherwise a `.env` file is\n * created at the project root.\n */\nconst ENV_FILE_CANDIDATES = ['.env', '.env.local', '.env.development'] as const;\n\n/** Credentials returned by the CMS login flow (access key pair). */\nexport type CmsCredentials = {\n clientId: string;\n clientSecret: string;\n};\n\n/**\n * Resolves the first existing Intlayer configuration file at the project root,\n * or `undefined` when none is present.\n */\nconst findIntlayerConfigFile = async (\n rootDir: string\n): Promise<(typeof INTLAYER_CONFIG_FILE_CANDIDATES)[number] | undefined> => {\n for (const candidate of INTLAYER_CONFIG_FILE_CANDIDATES) {\n if (await exists(rootDir, candidate)) {\n return candidate;\n }\n }\n\n return undefined;\n};\n\n/**\n * Locates the environment file the CMS credentials should be written to. Uses\n * `fast-glob` to detect an existing dotenv file at the project root, preferring\n * a plain `.env`; falls back to `.env` (to be created) when none exist.\n */\nexport const findEnvFile = async (rootDir: string): Promise<string> => {\n const matches = await fg([...ENV_FILE_CANDIDATES], {\n cwd: rootDir,\n dot: true,\n deep: 1,\n onlyFiles: true,\n });\n\n return (\n ENV_FILE_CANDIDATES.find((candidate) => matches.includes(candidate)) ??\n '.env'\n );\n};\n\n/**\n * Inserts or updates a `KEY=value` line in dotenv file content. An existing\n * assignment of the same key is replaced in place; otherwise the line is\n * appended with a trailing newline.\n */\nconst upsertEnvVariable = (\n content: string,\n key: string,\n value: string\n): string => {\n const line = `${key}=${value}`;\n const keyMatcher = new RegExp(`^${key}=.*$`, 'm');\n\n if (keyMatcher.test(content)) {\n return content.replace(keyMatcher, line);\n }\n\n const needsLeadingNewline = content.length > 0 && !content.endsWith('\\n');\n\n return `${content}${needsLeadingNewline ? '\\n' : ''}${line}\\n`;\n};\n\n/**\n * Persists the CMS access-key credentials to the project's environment file as\n * `INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET`. The target file is detected\n * with {@link findEnvFile} and created when missing. Returns the relative path\n * of the file that was written.\n */\nexport const writeCmsCredentialsToEnv = async (\n rootDir: string,\n { clientId, clientSecret }: CmsCredentials\n): Promise<string> => {\n const envFile = await findEnvFile(rootDir);\n\n let content = '';\n if (await exists(rootDir, envFile)) {\n content = await readFileFromRoot(rootDir, envFile);\n }\n\n let updatedContent = content;\n updatedContent = upsertEnvVariable(\n updatedContent,\n 'INTLAYER_CLIENT_ID',\n clientId\n );\n updatedContent = upsertEnvVariable(\n updatedContent,\n 'INTLAYER_CLIENT_SECRET',\n clientSecret\n );\n\n await writeFileToRoot(rootDir, envFile, updatedContent);\n logger(\n `${v} Saved Intlayer CMS credentials to ${colorizePath(envFile)} (${colorize('INTLAYER_CLIENT_ID', ANSIColors.GREY_LIGHT)}, ${colorize('INTLAYER_CLIENT_SECRET', ANSIColors.GREY_LIGHT)})`\n );\n\n return envFile;\n};\n\n/**\n * Enables the Intlayer visual editor in the project's configuration file:\n * flips `editor.enabled` to `true` and wires `clientId` / `clientSecret` to the\n * matching environment variables. JSON configs cannot reference `process.env`,\n * so they are skipped with a warning. Returns the config file that was updated,\n * or `undefined` when no editable config was found.\n */\nexport const enableEditorInConfig = async (\n rootDir: string\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) {\n logger(\n `${x} Could not find an Intlayer configuration file to enable the editor.`,\n { level: 'warn' }\n );\n return undefined;\n }\n\n const extension = configFile.split('.').pop()!;\n\n if (extension === 'json') {\n logger(\n `${x} ${colorizePath(configFile)} is a JSON config and cannot reference environment variables. Enable the editor and set clientId/clientSecret manually.`,\n { level: 'warn' }\n );\n return undefined;\n }\n\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = enableIntlayerEditorConfig(content);\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(`${v} Enabled the Intlayer editor in ${colorizePath(configFile)}`);\n } else {\n logger(\n `${v} ${colorizePath(configFile)} already has the Intlayer editor enabled`\n );\n }\n\n return configFile;\n};\n\n/**\n * Sets `routing.mode` in the project's Intlayer configuration file. Returns the\n * config file that was updated, or `undefined` when none was found.\n */\nexport const setRoutingModeInConfig = async (\n rootDir: string,\n mode: RoutingMode\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) return undefined;\n\n const extension = configFile.split('.').pop()!;\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = setIntlayerConfigRoutingMode(content, extension, mode);\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(\n `${v} Set ${colorize(`routing.mode = '${mode}'`, ANSIColors.GREY_LIGHT)} in ${colorizePath(configFile)}`\n );\n }\n\n return configFile;\n};\n\n/**\n * Completes the CMS setup once credentials are received from the login flow:\n * writes them to the environment file and enables the editor in the Intlayer\n * configuration file.\n */\nexport const setupCmsCredentials = async (\n rootDir: string,\n credentials: CmsCredentials\n): Promise<void> => {\n await writeCmsCredentialsToEnv(rootDir, credentials);\n await enableEditorInConfig(rootDir);\n};\n"],"mappings":";;;;;;;;;;;;;;;AAcA,MAAa,kCAAkC;CAC7C;CACA;CACA;CACA;CACA;CACD;;;;;;AAOD,MAAM,sBAAsB;CAAC;CAAQ;CAAc;CAAmB;;;;;AAYtE,MAAM,yBAAyB,OAC7B,YAC0E;AAC1E,MAAK,MAAM,aAAa,gCACtB,KAAI,MAAMA,qCAAO,SAAS,UAAU,CAClC,QAAO;;;;;;;AAYb,MAAa,cAAc,OAAO,YAAqC;CACrE,MAAM,UAAU,6BAAS,CAAC,GAAG,oBAAoB,EAAE;EACjD,KAAK;EACL,KAAK;EACL,MAAM;EACN,WAAW;EACZ,CAAC;AAEF,QACE,oBAAoB,MAAM,cAAc,QAAQ,SAAS,UAAU,CAAC,IACpE;;;;;;;AASJ,MAAM,qBACJ,SACA,KACA,UACW;CACX,MAAM,OAAO,GAAG,IAAI,GAAG;CACvB,MAAM,aAAa,IAAI,OAAO,IAAI,IAAI,OAAO,IAAI;AAEjD,KAAI,WAAW,KAAK,QAAQ,CAC1B,QAAO,QAAQ,QAAQ,YAAY,KAAK;AAK1C,QAAO,GAAG,UAFkB,QAAQ,SAAS,KAAK,CAAC,QAAQ,SAAS,KAAK,GAE/B,OAAO,KAAK,KAAK;;;;;;;;AAS7D,MAAa,2BAA2B,OACtC,SACA,EAAE,UAAU,mBACQ;CACpB,MAAM,UAAU,MAAM,YAAY,QAAQ;CAE1C,IAAI,UAAU;AACd,KAAI,MAAMA,qCAAO,SAAS,QAAQ,CAChC,WAAU,MAAMC,+CAAiB,SAAS,QAAQ;CAGpD,IAAI,iBAAiB;AACrB,kBAAiB,kBACf,gBACA,sBACA,SACD;AACD,kBAAiB,kBACf,gBACA,0BACA,aACD;AAED,OAAMC,8CAAgB,SAAS,SAAS,eAAe;AACvD,qCACE,GAAGC,0BAAE,+EAAkD,QAAQ,CAAC,0CAAa,sBAAsBC,wBAAW,WAAW,CAAC,0CAAa,0BAA0BA,wBAAW,WAAW,CAAC,GACzL;AAED,QAAO;;;;;;;;;AAUT,MAAa,uBAAuB,OAClC,YACgC;CAChC,MAAM,aAAa,MAAM,uBAAuB,QAAQ;AAExD,KAAI,CAAC,YAAY;AACf,sCACE,GAAGC,0BAAE,uEACL,EAAE,OAAO,QAAQ,CAClB;AACD;;AAKF,KAFkB,WAAW,MAAM,IAAI,CAAC,KAE3B,KAAK,QAAQ;AACxB,sCACE,GAAGA,0BAAE,6CAAgB,WAAW,CAAC,0HACjC,EAAE,OAAO,QAAQ,CAClB;AACD;;CAGF,MAAM,UAAU,MAAMJ,+CAAiB,SAAS,WAAW;CAC3D,MAAM,iBAAiBK,iEAA2B,QAAQ;AAE1D,KAAI,mBAAmB,SAAS;AAC9B,QAAMJ,8CAAgB,SAAS,YAAY,eAAe;AAC1D,sCAAO,GAAGC,0BAAE,4EAA+C,WAAW,GAAG;OAEzE,qCACE,GAAGA,0BAAE,6CAAgB,WAAW,CAAC,0CAClC;AAGH,QAAO;;;;;;AAOT,MAAa,yBAAyB,OACpC,SACA,SACgC;CAChC,MAAM,aAAa,MAAM,uBAAuB,QAAQ;AAExD,KAAI,CAAC,WAAY,QAAO;CAExB,MAAM,YAAY,WAAW,MAAM,IAAI,CAAC,KAAK;CAC7C,MAAM,UAAU,MAAMF,+CAAiB,SAAS,WAAW;CAC3D,MAAM,iBAAiBM,mEAA6B,SAAS,WAAW,KAAK;AAE7E,KAAI,mBAAmB,SAAS;AAC9B,QAAML,8CAAgB,SAAS,YAAY,eAAe;AAC1D,sCACE,GAAGC,0BAAE,6CAAgB,mBAAmB,KAAK,IAAIC,wBAAW,WAAW,CAAC,gDAAmB,WAAW,GACvG;;AAGH,QAAO;;;;;;;AAQT,MAAa,sBAAsB,OACjC,SACA,gBACkB;AAClB,OAAM,yBAAyB,SAAS,YAAY;AACpD,OAAM,qBAAqB,QAAQ"}
|
|
@@ -69,7 +69,7 @@ const ensureExportFrom = (ast, exportedName, source) => {
|
|
|
69
69
|
const ensureAwaitedLocale = (funcNode) => {
|
|
70
70
|
funcNode.async = true;
|
|
71
71
|
if (funcNode.body.type !== "BlockStatement") funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);
|
|
72
|
-
if (!funcNode.body.body.some((stmt) => stmt.type === "VariableDeclaration" && stmt.declarations.some((d) => d.id?.type === "Identifier" && d.id.name === "locale"))) {
|
|
72
|
+
if (!funcNode.body.body.some((stmt) => stmt.type === "VariableDeclaration" && stmt.declarations.some((d) => d.id?.type === "Identifier" && d.id.name === "locale" || d.id?.type === "ObjectPattern" && d.id.properties?.some((prop) => prop.value?.type === "Identifier" && prop.value?.name === "locale")))) {
|
|
73
73
|
const localeStatement = parseTsx("const locale = await getLocale();").program.body[0];
|
|
74
74
|
funcNode.body.body.unshift(localeStatement);
|
|
75
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transforms.cjs","names":[],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/transforms.ts"],"sourcesContent":["import * as recast from 'recast';\n\nconst { builders: b } = recast.types;\n\n/** babel-ts parser handles TypeScript *and* JSX (the `typescript` parser does not). */\nconst parseTsx = (code: string): any =>\n recast.parse(code, { parser: require('recast/parsers/babel-ts') });\n\n/** Result of a source transform. `code` is unchanged for any non-`wrapped` status. */\nexport type TransformResult = {\n code: string;\n status: 'wrapped' | 'already' | 'skipped-client' | 'skipped';\n};\n\n/** Detects a top-level `'use client'` directive (client components can't be async server providers). */\nconst isClientComponent = (ast: any): boolean => {\n const directives = ast.program.directives ?? [];\n if (\n directives.some((directive: any) => directive.value?.value === 'use client')\n ) {\n return true;\n }\n return ast.program.body.some(\n (stmt: any) =>\n stmt.type === 'ExpressionStatement' &&\n stmt.expression?.type === 'StringLiteral' &&\n stmt.expression.value === 'use client'\n );\n};\n\n/** Finds the function node behind `export default`, following an identifier reference if needed. */\nconst findDefaultExportFunction = (ast: any): any => {\n const body = ast.program.body;\n\n const asFunction = (node: any): any =>\n node &&\n (node.type === 'ArrowFunctionExpression' ||\n node.type === 'FunctionExpression' ||\n node.type === 'FunctionDeclaration')\n ? node\n : null;\n\n for (const stmt of body) {\n if (stmt.type !== 'ExportDefaultDeclaration') continue;\n\n const direct = asFunction(stmt.declaration);\n if (direct) return direct;\n\n if (stmt.declaration?.type === 'Identifier') {\n const name = stmt.declaration.name;\n for (const candidate of body) {\n if (candidate.type === 'VariableDeclaration') {\n for (const declarator of candidate.declarations) {\n if (\n declarator.id?.type === 'Identifier' &&\n declarator.id.name === name\n ) {\n const fn = asFunction(declarator.init);\n if (fn) return fn;\n }\n }\n }\n if (\n candidate.type === 'FunctionDeclaration' &&\n candidate.id?.name === name\n ) {\n return candidate;\n }\n }\n }\n }\n\n return null;\n};\n\n/** Index just past the leading directives + import declarations, where new top-level code is safe to insert. */\nconst firstInsertIndex = (ast: any): number => {\n const body = ast.program.body;\n let index = 0;\n while (\n index < body.length &&\n ((body[index].type === 'ExpressionStatement' &&\n body[index].expression?.type === 'StringLiteral') ||\n body[index].type === 'ImportDeclaration')\n ) {\n index++;\n }\n return index;\n};\n\n/** Ensures `import { importName } from source`, merging into an existing import from the same source. */\nconst ensureNamedImport = (\n ast: any,\n importName: string,\n source: string\n): void => {\n for (const stmt of ast.program.body) {\n if (stmt.type === 'ImportDeclaration' && stmt.source.value === source) {\n const hasSpecifier = stmt.specifiers.some(\n (spec: any) =>\n spec.type === 'ImportSpecifier' && spec.imported?.name === importName\n );\n if (!hasSpecifier) {\n stmt.specifiers.push(b.importSpecifier(b.identifier(importName)));\n }\n return;\n }\n }\n\n const declaration = b.importDeclaration(\n [b.importSpecifier(b.identifier(importName))],\n b.stringLiteral(source)\n );\n ast.program.body.splice(firstInsertIndex(ast), 0, declaration);\n};\n\n/** Ensures `export { exportedName } from source`, skipping when already declared/re-exported. */\nconst ensureExportFrom = (\n ast: any,\n exportedName: string,\n source: string\n): void => {\n const body = ast.program.body;\n\n const alreadyPresent = body.some((stmt: any) => {\n if (\n stmt.type === 'ExportNamedDeclaration' &&\n stmt.source?.value === source\n ) {\n return stmt.specifiers.some(\n (spec: any) => spec.exported?.name === exportedName\n );\n }\n // Locally declared `export const/function generateStaticParams`\n if (stmt.type === 'ExportNamedDeclaration' && stmt.declaration) {\n const decl = stmt.declaration;\n if (decl.type === 'FunctionDeclaration' && decl.id?.name === exportedName)\n return true;\n if (decl.type === 'VariableDeclaration') {\n return decl.declarations.some(\n (d: any) => d.id?.type === 'Identifier' && d.id.name === exportedName\n );\n }\n }\n return false;\n });\n\n if (alreadyPresent) return;\n\n const exportNode = parseTsx(`export { ${exportedName} } from \"${source}\";`)\n .program.body[0];\n ast.program.body.splice(firstInsertIndex(ast), 0, exportNode);\n};\n\n/** Makes the function async and inserts `const locale = await getLocale();` once, at the top of its body. */\nconst ensureAwaitedLocale = (funcNode: any): void => {\n funcNode.async = true;\n\n if (funcNode.body.type !== 'BlockStatement') {\n funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);\n }\n\n const hasLocale = funcNode.body.body.some(\n (stmt: any) =>\n stmt.type === 'VariableDeclaration' &&\n stmt.declarations.some(\n (d: any) => d.id?.type === 'Identifier' && d.id.name === 'locale'\n )\n );\n\n if (!hasLocale) {\n const localeStatement = parseTsx('const locale = await getLocale();')\n .program.body[0];\n funcNode.body.body.unshift(localeStatement);\n }\n};\n\n/** Builds `<providerName locale={locale}>{child}</providerName>` around an existing JSX child node. */\nconst buildProviderElement = (providerName: string, childNode: any): any => {\n const template = parseTsx(\n `const __wrap = <${providerName} locale={locale}>{__child__}</${providerName}>;`\n );\n const providerElement = template.program.body[0].declarations[0].init;\n providerElement.children = [childNode];\n return providerElement;\n};\n\n/** Sets `lang={locale}` on the first `<html>` element, if present. */\nconst setHtmlLang = (ast: any): void => {\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type === 'JSXIdentifier' && node.name.name === 'html') {\n const langAttr = node.attributes?.find(\n (attr: any) =>\n attr.type === 'JSXAttribute' && attr.name?.name === 'lang'\n ) as any;\n const localeExpression = b.jsxExpressionContainer(\n b.identifier('locale')\n );\n if (langAttr) {\n langAttr.value = localeExpression;\n } else {\n node.attributes.push(\n b.jsxAttribute(b.jsxIdentifier('lang'), localeExpression)\n );\n }\n return false;\n }\n this.traverse(path);\n },\n });\n};\n\n/**\n * Wraps the `{children}` of a Next.js App Router **layout** with\n * `IntlayerClientProvider`, deriving the locale via `getLocale()`. Safe and\n * idempotent: bails (returns the original code) for client components, when no\n * `{children}` placeholder is found, or when there is no default export.\n */\nexport const wrapLayoutWithProvider = (code: string): TransformResult => {\n const ast = parseTsx(code);\n\n if (isClientComponent(ast)) return { code, status: 'skipped-client' };\n if (code.includes('IntlayerClientProvider'))\n return { code, status: 'already' };\n\n const funcNode = findDefaultExportFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n let wrapped = false;\n recast.visit(funcNode, {\n visitJSXExpressionContainer(path) {\n if (wrapped) return false;\n const expression = path.node.expression;\n if (expression?.type === 'Identifier' && expression.name === 'children') {\n path.replace(buildProviderElement('IntlayerClientProvider', path.node));\n wrapped = true;\n return false;\n }\n this.traverse(path);\n },\n });\n\n if (!wrapped) return { code, status: 'skipped' };\n\n ensureNamedImport(ast, 'IntlayerClientProvider', 'next-intlayer');\n ensureNamedImport(ast, 'getLocale', 'next-intlayer/server');\n ensureExportFrom(ast, 'generateStaticParams', 'next-intlayer');\n ensureAwaitedLocale(funcNode);\n setHtmlLang(ast);\n\n return { code: recast.print(ast).code, status: 'wrapped' };\n};\n\n/** Returns the single top-level JSX return of a function, or the JSX of an expression-bodied arrow. */\nconst findSingleJsxReturn = (\n funcNode: any\n): { kind: 'return'; node: any } | { kind: 'arrow'; node: any } | null => {\n if (\n funcNode.type === 'ArrowFunctionExpression' &&\n funcNode.body.type !== 'BlockStatement'\n ) {\n const body =\n funcNode.body.type === 'JSXElement' ||\n funcNode.body.type === 'JSXFragment'\n ? funcNode.body\n : null;\n return body ? { kind: 'arrow', node: funcNode } : null;\n }\n\n if (funcNode.body.type !== 'BlockStatement') return null;\n\n // Collect every JSX-returning `return` inside this function, but do not\n // descend into nested function scopes (e.g. an inner component defined in the\n // same file). More than one top-level JSX return is ambiguous — bail.\n const jsxReturns: any[] = [];\n let functionDepth = 0;\n recast.visit(funcNode, {\n visitFunction(path) {\n functionDepth++;\n if (functionDepth === 1) {\n this.traverse(path);\n }\n functionDepth--;\n return false;\n },\n visitReturnStatement(path) {\n const argument = path.node.argument;\n if (argument?.type === 'JSXElement' || argument?.type === 'JSXFragment') {\n jsxReturns.push(path.node);\n }\n this.traverse(path);\n },\n });\n\n if (jsxReturns.length !== 1) return null;\n return { kind: 'return', node: jsxReturns[0] };\n};\n\n/**\n * Wraps the returned JSX of a Next.js App Router **page** with\n * `IntlayerServerProvider`, deriving the locale via `getLocale()`. Safe and\n * idempotent: bails for client components, when the page has no single\n * top-level JSX return, or when there is no default export.\n */\nexport const wrapPageWithProvider = (code: string): TransformResult => {\n const ast = parseTsx(code);\n\n if (isClientComponent(ast)) return { code, status: 'skipped-client' };\n if (code.includes('IntlayerServerProvider'))\n return { code, status: 'already' };\n\n const funcNode = findDefaultExportFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n const jsxReturn = findSingleJsxReturn(funcNode);\n if (!jsxReturn) return { code, status: 'skipped' };\n\n if (jsxReturn.kind === 'return') {\n jsxReturn.node.argument = buildProviderElement(\n 'IntlayerServerProvider',\n jsxReturn.node.argument\n );\n } else {\n jsxReturn.node.body = buildProviderElement(\n 'IntlayerServerProvider',\n jsxReturn.node.body\n );\n }\n\n ensureNamedImport(ast, 'IntlayerServerProvider', 'next-intlayer/server');\n ensureNamedImport(ast, 'getLocale', 'next-intlayer/server');\n ensureAwaitedLocale(funcNode);\n\n return { code: recast.print(ast).code, status: 'wrapped' };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transforms.cjs","names":[],"sources":["../../../../../src/init/frameworkSetup/nextAppRouter/transforms.ts"],"sourcesContent":["import * as recast from 'recast';\n\nconst { builders: b } = recast.types;\n\n/** babel-ts parser handles TypeScript *and* JSX (the `typescript` parser does not). */\nconst parseTsx = (code: string): any =>\n recast.parse(code, { parser: require('recast/parsers/babel-ts') });\n\n/** Result of a source transform. `code` is unchanged for any non-`wrapped` status. */\nexport type TransformResult = {\n code: string;\n status: 'wrapped' | 'already' | 'skipped-client' | 'skipped';\n};\n\n/** Detects a top-level `'use client'` directive (client components can't be async server providers). */\nconst isClientComponent = (ast: any): boolean => {\n const directives = ast.program.directives ?? [];\n if (\n directives.some((directive: any) => directive.value?.value === 'use client')\n ) {\n return true;\n }\n return ast.program.body.some(\n (stmt: any) =>\n stmt.type === 'ExpressionStatement' &&\n stmt.expression?.type === 'StringLiteral' &&\n stmt.expression.value === 'use client'\n );\n};\n\n/** Finds the function node behind `export default`, following an identifier reference if needed. */\nconst findDefaultExportFunction = (ast: any): any => {\n const body = ast.program.body;\n\n const asFunction = (node: any): any =>\n node &&\n (node.type === 'ArrowFunctionExpression' ||\n node.type === 'FunctionExpression' ||\n node.type === 'FunctionDeclaration')\n ? node\n : null;\n\n for (const stmt of body) {\n if (stmt.type !== 'ExportDefaultDeclaration') continue;\n\n const direct = asFunction(stmt.declaration);\n if (direct) return direct;\n\n if (stmt.declaration?.type === 'Identifier') {\n const name = stmt.declaration.name;\n for (const candidate of body) {\n if (candidate.type === 'VariableDeclaration') {\n for (const declarator of candidate.declarations) {\n if (\n declarator.id?.type === 'Identifier' &&\n declarator.id.name === name\n ) {\n const fn = asFunction(declarator.init);\n if (fn) return fn;\n }\n }\n }\n if (\n candidate.type === 'FunctionDeclaration' &&\n candidate.id?.name === name\n ) {\n return candidate;\n }\n }\n }\n }\n\n return null;\n};\n\n/** Index just past the leading directives + import declarations, where new top-level code is safe to insert. */\nconst firstInsertIndex = (ast: any): number => {\n const body = ast.program.body;\n let index = 0;\n while (\n index < body.length &&\n ((body[index].type === 'ExpressionStatement' &&\n body[index].expression?.type === 'StringLiteral') ||\n body[index].type === 'ImportDeclaration')\n ) {\n index++;\n }\n return index;\n};\n\n/** Ensures `import { importName } from source`, merging into an existing import from the same source. */\nconst ensureNamedImport = (\n ast: any,\n importName: string,\n source: string\n): void => {\n for (const stmt of ast.program.body) {\n if (stmt.type === 'ImportDeclaration' && stmt.source.value === source) {\n const hasSpecifier = stmt.specifiers.some(\n (spec: any) =>\n spec.type === 'ImportSpecifier' && spec.imported?.name === importName\n );\n if (!hasSpecifier) {\n stmt.specifiers.push(b.importSpecifier(b.identifier(importName)));\n }\n return;\n }\n }\n\n const declaration = b.importDeclaration(\n [b.importSpecifier(b.identifier(importName))],\n b.stringLiteral(source)\n );\n ast.program.body.splice(firstInsertIndex(ast), 0, declaration);\n};\n\n/** Ensures `export { exportedName } from source`, skipping when already declared/re-exported. */\nconst ensureExportFrom = (\n ast: any,\n exportedName: string,\n source: string\n): void => {\n const body = ast.program.body;\n\n const alreadyPresent = body.some((stmt: any) => {\n if (\n stmt.type === 'ExportNamedDeclaration' &&\n stmt.source?.value === source\n ) {\n return stmt.specifiers.some(\n (spec: any) => spec.exported?.name === exportedName\n );\n }\n // Locally declared `export const/function generateStaticParams`\n if (stmt.type === 'ExportNamedDeclaration' && stmt.declaration) {\n const decl = stmt.declaration;\n if (decl.type === 'FunctionDeclaration' && decl.id?.name === exportedName)\n return true;\n if (decl.type === 'VariableDeclaration') {\n return decl.declarations.some(\n (d: any) => d.id?.type === 'Identifier' && d.id.name === exportedName\n );\n }\n }\n return false;\n });\n\n if (alreadyPresent) return;\n\n const exportNode = parseTsx(`export { ${exportedName} } from \"${source}\";`)\n .program.body[0];\n ast.program.body.splice(firstInsertIndex(ast), 0, exportNode);\n};\n\n/** Makes the function async and inserts `const locale = await getLocale();` once, at the top of its body. */\nconst ensureAwaitedLocale = (funcNode: any): void => {\n funcNode.async = true;\n\n if (funcNode.body.type !== 'BlockStatement') {\n funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);\n }\n\n const hasLocale = funcNode.body.body.some(\n (stmt: any) =>\n stmt.type === 'VariableDeclaration' &&\n stmt.declarations.some(\n (d: any) =>\n // const locale = ...\n (d.id?.type === 'Identifier' && d.id.name === 'locale') ||\n // const { locale } = ... or const { locale: locale } = ...\n (d.id?.type === 'ObjectPattern' &&\n d.id.properties?.some(\n (prop: any) =>\n prop.value?.type === 'Identifier' &&\n prop.value?.name === 'locale'\n ))\n )\n );\n\n if (!hasLocale) {\n const localeStatement = parseTsx('const locale = await getLocale();')\n .program.body[0];\n funcNode.body.body.unshift(localeStatement);\n }\n};\n\n/** Builds `<providerName locale={locale}>{child}</providerName>` around an existing JSX child node. */\nconst buildProviderElement = (providerName: string, childNode: any): any => {\n const template = parseTsx(\n `const __wrap = <${providerName} locale={locale}>{__child__}</${providerName}>;`\n );\n const providerElement = template.program.body[0].declarations[0].init;\n providerElement.children = [childNode];\n return providerElement;\n};\n\n/** Sets `lang={locale}` on the first `<html>` element, if present. */\nconst setHtmlLang = (ast: any): void => {\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type === 'JSXIdentifier' && node.name.name === 'html') {\n const langAttr = node.attributes?.find(\n (attr: any) =>\n attr.type === 'JSXAttribute' && attr.name?.name === 'lang'\n ) as any;\n const localeExpression = b.jsxExpressionContainer(\n b.identifier('locale')\n );\n if (langAttr) {\n langAttr.value = localeExpression;\n } else {\n node.attributes.push(\n b.jsxAttribute(b.jsxIdentifier('lang'), localeExpression)\n );\n }\n return false;\n }\n this.traverse(path);\n },\n });\n};\n\n/**\n * Wraps the `{children}` of a Next.js App Router **layout** with\n * `IntlayerClientProvider`, deriving the locale via `getLocale()`. Safe and\n * idempotent: bails (returns the original code) for client components, when no\n * `{children}` placeholder is found, or when there is no default export.\n */\nexport const wrapLayoutWithProvider = (code: string): TransformResult => {\n const ast = parseTsx(code);\n\n if (isClientComponent(ast)) return { code, status: 'skipped-client' };\n if (code.includes('IntlayerClientProvider'))\n return { code, status: 'already' };\n\n const funcNode = findDefaultExportFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n let wrapped = false;\n recast.visit(funcNode, {\n visitJSXExpressionContainer(path) {\n if (wrapped) return false;\n const expression = path.node.expression;\n if (expression?.type === 'Identifier' && expression.name === 'children') {\n path.replace(buildProviderElement('IntlayerClientProvider', path.node));\n wrapped = true;\n return false;\n }\n this.traverse(path);\n },\n });\n\n if (!wrapped) return { code, status: 'skipped' };\n\n ensureNamedImport(ast, 'IntlayerClientProvider', 'next-intlayer');\n ensureNamedImport(ast, 'getLocale', 'next-intlayer/server');\n ensureExportFrom(ast, 'generateStaticParams', 'next-intlayer');\n ensureAwaitedLocale(funcNode);\n setHtmlLang(ast);\n\n return { code: recast.print(ast).code, status: 'wrapped' };\n};\n\n/** Returns the single top-level JSX return of a function, or the JSX of an expression-bodied arrow. */\nconst findSingleJsxReturn = (\n funcNode: any\n): { kind: 'return'; node: any } | { kind: 'arrow'; node: any } | null => {\n if (\n funcNode.type === 'ArrowFunctionExpression' &&\n funcNode.body.type !== 'BlockStatement'\n ) {\n const body =\n funcNode.body.type === 'JSXElement' ||\n funcNode.body.type === 'JSXFragment'\n ? funcNode.body\n : null;\n return body ? { kind: 'arrow', node: funcNode } : null;\n }\n\n if (funcNode.body.type !== 'BlockStatement') return null;\n\n // Collect every JSX-returning `return` inside this function, but do not\n // descend into nested function scopes (e.g. an inner component defined in the\n // same file). More than one top-level JSX return is ambiguous — bail.\n const jsxReturns: any[] = [];\n let functionDepth = 0;\n recast.visit(funcNode, {\n visitFunction(path) {\n functionDepth++;\n if (functionDepth === 1) {\n this.traverse(path);\n }\n functionDepth--;\n return false;\n },\n visitReturnStatement(path) {\n const argument = path.node.argument;\n if (argument?.type === 'JSXElement' || argument?.type === 'JSXFragment') {\n jsxReturns.push(path.node);\n }\n this.traverse(path);\n },\n });\n\n if (jsxReturns.length !== 1) return null;\n return { kind: 'return', node: jsxReturns[0] };\n};\n\n/**\n * Wraps the returned JSX of a Next.js App Router **page** with\n * `IntlayerServerProvider`, deriving the locale via `getLocale()`. Safe and\n * idempotent: bails for client components, when the page has no single\n * top-level JSX return, or when there is no default export.\n */\nexport const wrapPageWithProvider = (code: string): TransformResult => {\n const ast = parseTsx(code);\n\n if (isClientComponent(ast)) return { code, status: 'skipped-client' };\n if (code.includes('IntlayerServerProvider'))\n return { code, status: 'already' };\n\n const funcNode = findDefaultExportFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n const jsxReturn = findSingleJsxReturn(funcNode);\n if (!jsxReturn) return { code, status: 'skipped' };\n\n if (jsxReturn.kind === 'return') {\n jsxReturn.node.argument = buildProviderElement(\n 'IntlayerServerProvider',\n jsxReturn.node.argument\n );\n } else {\n jsxReturn.node.body = buildProviderElement(\n 'IntlayerServerProvider',\n jsxReturn.node.body\n );\n }\n\n ensureNamedImport(ast, 'IntlayerServerProvider', 'next-intlayer/server');\n ensureNamedImport(ast, 'getLocale', 'next-intlayer/server');\n ensureAwaitedLocale(funcNode);\n\n return { code: recast.print(ast).code, status: 'wrapped' };\n};\n"],"mappings":"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"}
|
package/dist/cjs/init/index.cjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
3
|
-
const
|
|
3
|
+
const require_init_utils_configManipulation = require('./utils/configManipulation.cjs');
|
|
4
4
|
const require_init_utils_fileSystem = require('./utils/fileSystem.cjs');
|
|
5
|
+
const require_init_cms = require('./cms.cjs');
|
|
6
|
+
const require_initConfig_index = require('../initConfig/index.cjs');
|
|
5
7
|
const require_init_frameworkSetup_index = require('./frameworkSetup/index.cjs');
|
|
6
|
-
const require_init_utils_configManipulation = require('./utils/configManipulation.cjs');
|
|
7
8
|
const require_init_utils_githubActions = require('./utils/githubActions.cjs');
|
|
8
9
|
const require_init_utils_jsonParser = require('./utils/jsonParser.cjs');
|
|
9
10
|
const require_init_utils_packageManager = require('./utils/packageManager.cjs');
|
|
11
|
+
const require_init_utils_nextCompilerBabel = require('./utils/nextCompilerBabel.cjs');
|
|
10
12
|
const require_init_utils_tsConfig = require('./utils/tsConfig.cjs');
|
|
11
13
|
let node_path = require("node:path");
|
|
12
14
|
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
@@ -127,10 +129,11 @@ const initIntlayer = async (rootDir, options) => {
|
|
|
127
129
|
const packageManager = require_init_utils_packageManager.detectPackageManager(rootDir);
|
|
128
130
|
const { packagesToInstall, devPackagesToInstall, compatSyncConfig, compatVitePluginConfig } = require_init_utils_packageManager.detectMissingIntlayerPackages(allDeps);
|
|
129
131
|
if (!options?.noInstallPackages) {
|
|
132
|
+
const withVersion = (packages) => options?.upgradeToVersion ? packages.map((pkg) => `${pkg}@${options.upgradeToVersion}`) : packages;
|
|
130
133
|
if (packagesToInstall.length > 0) {
|
|
131
134
|
(0, _intlayer_config_logger.logger)((0, _intlayer_config_logger.colorize)("Installing missing Intlayer dependencies...", _intlayer_config_colors.CYAN));
|
|
132
135
|
try {
|
|
133
|
-
require_init_utils_packageManager.installPackages(rootDir, packagesToInstall, packageManager);
|
|
136
|
+
require_init_utils_packageManager.installPackages(rootDir, withVersion(packagesToInstall), packageManager);
|
|
134
137
|
(0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Installed: ${packagesToInstall.map((pkg) => (0, _intlayer_config_logger.colorize)(pkg, _intlayer_config_colors.MAGENTA)).join(", ")}`);
|
|
135
138
|
} catch {
|
|
136
139
|
(0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} Failed to install packages. Please install manually: ${packagesToInstall.join(" ")}`, { level: "warn" });
|
|
@@ -139,7 +142,7 @@ const initIntlayer = async (rootDir, options) => {
|
|
|
139
142
|
if (devPackagesToInstall.length > 0) {
|
|
140
143
|
(0, _intlayer_config_logger.logger)((0, _intlayer_config_logger.colorize)("Installing missing Intlayer dev dependencies...", _intlayer_config_colors.CYAN));
|
|
141
144
|
try {
|
|
142
|
-
require_init_utils_packageManager.installPackages(rootDir, devPackagesToInstall, packageManager, true);
|
|
145
|
+
require_init_utils_packageManager.installPackages(rootDir, withVersion(devPackagesToInstall), packageManager, true);
|
|
143
146
|
(0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Installed: ${devPackagesToInstall.map((pkg) => (0, _intlayer_config_logger.colorize)(pkg, _intlayer_config_colors.MAGENTA)).join(", ")}`);
|
|
144
147
|
} catch {
|
|
145
148
|
(0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} Failed to install dev packages. Please install manually: ${devPackagesToInstall.join(" ")}`, { level: "warn" });
|
|
@@ -266,6 +269,7 @@ const initIntlayer = async (rootDir, options) => {
|
|
|
266
269
|
break;
|
|
267
270
|
}
|
|
268
271
|
}
|
|
272
|
+
if (options?.routingMode) await require_init_cms.setRoutingModeInConfig(rootDir, options.routingMode);
|
|
269
273
|
let hasAliasConfiguration = false;
|
|
270
274
|
for (const file of [
|
|
271
275
|
"vite.config.ts",
|
|
@@ -314,6 +318,12 @@ const initIntlayer = async (rootDir, options) => {
|
|
|
314
318
|
}
|
|
315
319
|
break;
|
|
316
320
|
}
|
|
321
|
+
if (isNextJsProject) await require_init_utils_nextCompilerBabel.setupNextCompilerBabelConfig({
|
|
322
|
+
rootDir,
|
|
323
|
+
packageManager,
|
|
324
|
+
allDeps,
|
|
325
|
+
skipInstall: Boolean(options?.noInstallPackages)
|
|
326
|
+
});
|
|
317
327
|
for (const file of [
|
|
318
328
|
"astro.config.mjs",
|
|
319
329
|
"astro.config.js",
|