@intlayer/cli 9.4.4 → 9.5.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 +0 -2
- package/dist/cjs/build.cjs +7 -0
- package/dist/cjs/build.cjs.map +1 -1
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/init.cjs +19 -19
- package/dist/cjs/init.cjs.map +1 -1
- package/dist/cjs/initBuildOptimization.cjs +15 -16
- package/dist/cjs/initBuildOptimization.cjs.map +1 -1
- package/dist/cjs/initCompiler.cjs +15 -55
- package/dist/cjs/initCompiler.cjs.map +1 -1
- package/dist/cjs/initMCP.cjs +12 -12
- package/dist/cjs/initMCP.cjs.map +1 -1
- package/dist/cjs/initSkills.cjs +12 -12
- package/dist/cjs/initSkills.cjs.map +1 -1
- package/dist/cjs/loadPrompts.cjs +18 -0
- package/dist/cjs/loadPrompts.cjs.map +1 -0
- package/dist/cjs/push/push.cjs +2 -1
- package/dist/cjs/push/push.cjs.map +1 -1
- package/dist/cjs/pushConfig.cjs +1 -1
- package/dist/cjs/pushConfig.cjs.map +1 -1
- package/dist/cjs/watch.cjs +5 -0
- package/dist/cjs/watch.cjs.map +1 -1
- package/dist/esm/build.mjs +8 -1
- package/dist/esm/build.mjs.map +1 -1
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/init.mjs +2 -1
- package/dist/esm/init.mjs.map +1 -1
- package/dist/esm/initBuildOptimization.mjs +2 -1
- package/dist/esm/initBuildOptimization.mjs.map +1 -1
- package/dist/esm/initCompiler.mjs +10 -48
- package/dist/esm/initCompiler.mjs.map +1 -1
- package/dist/esm/initMCP.mjs +2 -1
- package/dist/esm/initMCP.mjs.map +1 -1
- package/dist/esm/initSkills.mjs +2 -1
- package/dist/esm/initSkills.mjs.map +1 -1
- package/dist/esm/loadPrompts.mjs +17 -0
- package/dist/esm/loadPrompts.mjs.map +1 -0
- package/dist/esm/push/push.mjs +2 -1
- package/dist/esm/push/push.mjs.map +1 -1
- package/dist/esm/pushConfig.mjs +1 -1
- package/dist/esm/pushConfig.mjs.map +1 -1
- package/dist/esm/watch.mjs +6 -1
- package/dist/esm/watch.mjs.map +1 -1
- package/dist/types/build.d.ts.map +1 -1
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/init.d.ts.map +1 -1
- package/dist/types/initCompiler.d.ts +5 -2
- package/dist/types/initCompiler.d.ts.map +1 -1
- package/dist/types/loadPrompts.d.ts +17 -0
- package/dist/types/loadPrompts.d.ts.map +1 -0
- package/dist/types/push/push.d.ts.map +1 -1
- package/dist/types/watch.d.ts.map +1 -1
- package/package.json +13 -13
|
@@ -1,40 +1,12 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const
|
|
2
|
+
const require_loadPrompts = require('./loadPrompts.cjs');
|
|
3
3
|
const require_init = require('./init.cjs');
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
let node_path = require("node:path");
|
|
6
6
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
7
|
-
let _clack_prompts = require("@clack/prompts");
|
|
8
|
-
_clack_prompts = require_runtime.__toESM(_clack_prompts);
|
|
9
7
|
|
|
10
8
|
//#region src/initCompiler.ts
|
|
11
9
|
/**
|
|
12
|
-
* babel.config.js that runs the Intlayer compiler passes for Next.js.
|
|
13
|
-
*
|
|
14
|
-
* Mirrors the Next.js (Babel) tab of `docs/docs/en/compiler.md`: the extract
|
|
15
|
-
* plugin pulls inline content into dictionaries and the optimize plugin
|
|
16
|
-
* rewrites `useIntlayer` into direct dictionary imports. On Vite the same work
|
|
17
|
-
* is handled by the `intlayer()` plugin (which bundles the compiler in v9), so
|
|
18
|
-
* no Babel config is needed.
|
|
19
|
-
*/
|
|
20
|
-
const BABEL_COMPILER_CONFIG_CONTENT = `const {
|
|
21
|
-
intlayerExtractBabelPlugin,
|
|
22
|
-
intlayerOptimizeBabelPlugin,
|
|
23
|
-
getExtractPluginOptions,
|
|
24
|
-
getOptimizePluginOptions,
|
|
25
|
-
} = require("@intlayer/babel");
|
|
26
|
-
|
|
27
|
-
module.exports = {
|
|
28
|
-
presets: ["next/babel"],
|
|
29
|
-
plugins: [
|
|
30
|
-
// Extract content from components into dictionaries
|
|
31
|
-
[intlayerExtractBabelPlugin, getExtractPluginOptions()],
|
|
32
|
-
// Optimize imports by replacing useIntlayer with direct dictionary imports
|
|
33
|
-
[intlayerOptimizeBabelPlugin, getOptimizePluginOptions()],
|
|
34
|
-
],
|
|
35
|
-
};
|
|
36
|
-
`;
|
|
37
|
-
/**
|
|
38
10
|
* Reads the project dependencies and detects which framework the compiler
|
|
39
11
|
* should target. Next.js is checked before Vite because a Next.js project may
|
|
40
12
|
* transitively depend on Vite tooling.
|
|
@@ -62,54 +34,42 @@ const detectCompilerFramework = (root) => {
|
|
|
62
34
|
* - **Vite** — nothing to do: since v9 the compiler is built into the
|
|
63
35
|
* `intlayer()` plugin in `vite.config.ts`, so this only confirms the setup
|
|
64
36
|
* to the user.
|
|
65
|
-
* - **Next.js** — installs `@intlayer/babel
|
|
66
|
-
*
|
|
37
|
+
* - **Next.js** — installs `@intlayer/babel`, which is all that is needed:
|
|
38
|
+
* `withIntlayer` registers `next-intlayer/extractor-loader` on both webpack
|
|
39
|
+
* and Turbopack as soon as the package resolves. No `babel.config.js` is
|
|
40
|
+
* written — Turbopack never reads one, and on webpack its mere presence
|
|
41
|
+
* switches Next.js off SWC, taking the `@intlayer/swc` optimize pass with it.
|
|
67
42
|
*
|
|
68
43
|
* In non-interactive init this function is never called, so the compiler setup
|
|
69
44
|
* is left untouched.
|
|
70
45
|
*/
|
|
71
46
|
const initCompiler = async (projectRoot) => {
|
|
47
|
+
const p = await require_loadPrompts.loadPrompts();
|
|
72
48
|
const root = require_init.findProjectRoot(projectRoot ? (0, node_path.resolve)(projectRoot) : process.cwd());
|
|
73
49
|
const framework = detectCompilerFramework(root);
|
|
74
50
|
if (framework === "vite") {
|
|
75
|
-
|
|
51
|
+
p.log.info("Vite detected — the compiler is built into `intlayer()` in your vite.config. Nothing to configure.");
|
|
76
52
|
return;
|
|
77
53
|
}
|
|
78
54
|
if (framework !== "nextjs") {
|
|
79
|
-
|
|
55
|
+
p.log.warn("No supported framework detected for the compiler — skipping. See the compiler docs for manual setup.");
|
|
80
56
|
return;
|
|
81
57
|
}
|
|
82
|
-
|
|
58
|
+
p.intro("Configuring the Intlayer compiler for Next.js");
|
|
83
59
|
const packageManager = (0, _intlayer_engine_cli.detectPackageManager)(root);
|
|
84
60
|
const devPackagesToInstall = ["@intlayer/babel"];
|
|
85
|
-
const spinner =
|
|
61
|
+
const spinner = p.spinner();
|
|
86
62
|
spinner.start("Installing packages...");
|
|
87
63
|
try {
|
|
88
64
|
(0, _intlayer_engine_cli.installPackages)(root, devPackagesToInstall, packageManager, true);
|
|
89
65
|
spinner.stop(`Installed: ${devPackagesToInstall.join(", ")}`);
|
|
90
66
|
} catch {
|
|
91
67
|
spinner.stop("Package installation failed");
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
const existingBabelConfig = [
|
|
95
|
-
"babel.config.js",
|
|
96
|
-
"babel.config.cjs",
|
|
97
|
-
"babel.config.mjs",
|
|
98
|
-
"babel.config.ts",
|
|
99
|
-
".babelrc",
|
|
100
|
-
".babelrc.js"
|
|
101
|
-
].find((file) => (0, node_fs.existsSync)((0, node_path.join)(root, file)));
|
|
102
|
-
if (existingBabelConfig) {
|
|
103
|
-
_clack_prompts.log.warn(`${existingBabelConfig} already exists — add the Intlayer compiler plugins manually.`);
|
|
104
|
-
_clack_prompts.note(BABEL_COMPILER_CONFIG_CONTENT, "Plugins to add to your babel config");
|
|
105
|
-
} else try {
|
|
106
|
-
(0, node_fs.writeFileSync)((0, node_path.join)(root, "babel.config.js"), BABEL_COMPILER_CONFIG_CONTENT, { encoding: "utf-8" });
|
|
107
|
-
_clack_prompts.log.success("Created babel.config.js with the Intlayer compiler extract and optimize plugins");
|
|
108
|
-
} catch {
|
|
109
|
-
_clack_prompts.log.warn("Could not create babel.config.js — please create it manually.");
|
|
110
|
-
_clack_prompts.note(BABEL_COMPILER_CONFIG_CONTENT, "babel.config.js");
|
|
68
|
+
p.log.warn(`Please install manually: ${devPackagesToInstall.join(" ")} (dev dependency)`);
|
|
111
69
|
}
|
|
112
|
-
|
|
70
|
+
p.log.success("The compiler runs through `withIntlayer` in your next.config — nothing else to wire up.");
|
|
71
|
+
p.log.info("Set `compiler.enabled` in intlayer.config.ts to turn the extraction on.");
|
|
72
|
+
p.outro("Compiler configuration complete");
|
|
113
73
|
};
|
|
114
74
|
|
|
115
75
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initCompiler.cjs","names":["join","existsSync","readFileSync","findProjectRoot","resolve","detectPackageManager"
|
|
1
|
+
{"version":3,"file":"initCompiler.cjs","names":["join","existsSync","readFileSync","loadPrompts","findProjectRoot","resolve","detectPackageManager"],"sources":["../../src/initCompiler.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { detectPackageManager, installPackages } from '@intlayer/engine/cli';\nimport { findProjectRoot } from './init';\nimport { loadPrompts } from './loadPrompts';\n\n/** Framework the Intlayer compiler can be wired into during init. */\ntype CompilerFramework = 'vite' | 'nextjs' | 'unknown';\n\n/**\n * Reads the project dependencies and detects which framework the compiler\n * should target. Next.js is checked before Vite because a Next.js project may\n * transitively depend on Vite tooling.\n */\nconst detectCompilerFramework = (root: string): CompilerFramework => {\n try {\n const packageJsonPath = join(root, 'package.json');\n if (!existsSync(packageJsonPath)) return 'unknown';\n\n const { dependencies = {}, devDependencies = {} } = JSON.parse(\n readFileSync(packageJsonPath, 'utf-8')\n );\n const allDependencies = { ...dependencies, ...devDependencies };\n\n if (allDependencies.next) return 'nextjs';\n if (allDependencies.vite) return 'vite';\n\n return 'unknown';\n } catch {\n return 'unknown';\n }\n};\n\n/**\n * Scaffolds the Intlayer compiler for the current project during interactive\n * init.\n *\n * - **Vite** — nothing to do: since v9 the compiler is built into the\n * `intlayer()` plugin in `vite.config.ts`, so this only confirms the setup\n * to the user.\n * - **Next.js** — installs `@intlayer/babel`, which is all that is needed:\n * `withIntlayer` registers `next-intlayer/extractor-loader` on both webpack\n * and Turbopack as soon as the package resolves. No `babel.config.js` is\n * written — Turbopack never reads one, and on webpack its mere presence\n * switches Next.js off SWC, taking the `@intlayer/swc` optimize pass with it.\n *\n * In non-interactive init this function is never called, so the compiler setup\n * is left untouched.\n */\nexport const initCompiler = async (projectRoot?: string): Promise<void> => {\n const p = await loadPrompts();\n\n const root = findProjectRoot(\n projectRoot ? resolve(projectRoot) : process.cwd()\n );\n\n const framework = detectCompilerFramework(root);\n\n if (framework === 'vite') {\n // Since v9 the compiler is bundled inside intlayer() — nothing to scaffold.\n p.log.info(\n 'Vite detected — the compiler is built into `intlayer()` in your vite.config. Nothing to configure.'\n );\n return;\n }\n\n if (framework !== 'nextjs') {\n p.log.warn(\n 'No supported framework detected for the compiler — skipping. See the compiler docs for manual setup.'\n );\n return;\n }\n\n p.intro('Configuring the Intlayer compiler for Next.js');\n\n const packageManager = detectPackageManager(root);\n const devPackagesToInstall = ['@intlayer/babel'];\n\n const spinner = p.spinner();\n spinner.start('Installing packages...');\n\n try {\n installPackages(root, devPackagesToInstall, packageManager, true);\n spinner.stop(`Installed: ${devPackagesToInstall.join(', ')}`);\n } catch {\n spinner.stop('Package installation failed');\n p.log.warn(\n `Please install manually: ${devPackagesToInstall.join(' ')} (dev dependency)`\n );\n }\n\n p.log.success(\n 'The compiler runs through `withIntlayer` in your next.config — nothing else to wire up.'\n );\n p.log.info(\n 'Set `compiler.enabled` in intlayer.config.ts to turn the extraction on.'\n );\n\n p.outro('Compiler configuration complete');\n};\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAM,2BAA2B,SAAoC;CACnE,IAAI;EACF,MAAM,sBAAkBA,gBAAK,MAAM,cAAc;EACjD,IAAI,KAACC,oBAAW,eAAe,GAAG,OAAO;EAEzC,MAAM,EAAE,eAAe,CAAC,GAAG,kBAAkB,CAAC,MAAM,KAAK,UACvDC,sBAAa,iBAAiB,OAAO,CACvC;EACA,MAAM,kBAAkB;GAAE,GAAG;GAAc,GAAG;EAAgB;EAE9D,IAAI,gBAAgB,MAAM,OAAO;EACjC,IAAI,gBAAgB,MAAM,OAAO;EAEjC,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;AAkBA,MAAa,eAAe,OAAO,gBAAwC;CACzE,MAAM,IAAI,MAAMC,gCAAY;CAE5B,MAAM,OAAOC,6BACX,kBAAcC,mBAAQ,WAAW,IAAI,QAAQ,IAAI,CACnD;CAEA,MAAM,YAAY,wBAAwB,IAAI;CAE9C,IAAI,cAAc,QAAQ;EAExB,EAAE,IAAI,KACJ,oGACF;EACA;CACF;CAEA,IAAI,cAAc,UAAU;EAC1B,EAAE,IAAI,KACJ,sGACF;EACA;CACF;CAEA,EAAE,MAAM,+CAA+C;CAEvD,MAAM,qBAAiBC,2CAAqB,IAAI;CAChD,MAAM,uBAAuB,CAAC,iBAAiB;CAE/C,MAAM,UAAU,EAAE,QAAQ;CAC1B,QAAQ,MAAM,wBAAwB;CAEtC,IAAI;EACF,0CAAgB,MAAM,sBAAsB,gBAAgB,IAAI;EAChE,QAAQ,KAAK,cAAc,qBAAqB,KAAK,IAAI,GAAG;CAC9D,QAAQ;EACN,QAAQ,KAAK,6BAA6B;EAC1C,EAAE,IAAI,KACJ,4BAA4B,qBAAqB,KAAK,GAAG,EAAE,kBAC7D;CACF;CAEA,EAAE,IAAI,QACJ,yFACF;CACA,EAAE,IAAI,KACJ,yEACF;CAEA,EAAE,MAAM,iCAAiC;AAC3C"}
|
package/dist/cjs/initMCP.cjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_loadPrompts = require('./loadPrompts.cjs');
|
|
3
4
|
const require_initSkills = require('./initSkills.cjs');
|
|
4
5
|
const require_init = require('./init.cjs');
|
|
5
6
|
let node_path = require("node:path");
|
|
6
7
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
7
8
|
let enquirer = require("enquirer");
|
|
8
9
|
enquirer = require_runtime.__toESM(enquirer);
|
|
9
|
-
let _clack_prompts = require("@clack/prompts");
|
|
10
|
-
_clack_prompts = require_runtime.__toESM(_clack_prompts);
|
|
11
10
|
|
|
12
11
|
//#region src/initMCP.ts
|
|
13
12
|
const initMCP = async (projectRoot, preselectedPlatform) => {
|
|
13
|
+
const p = await require_loadPrompts.loadPrompts();
|
|
14
14
|
const root = require_init.findProjectRoot(projectRoot ? (0, node_path.resolve)(projectRoot) : process.cwd());
|
|
15
|
-
|
|
15
|
+
p.intro("Initializing Intlayer MCP Server");
|
|
16
16
|
let platform;
|
|
17
17
|
if (preselectedPlatform) platform = preselectedPlatform;
|
|
18
18
|
else {
|
|
@@ -31,15 +31,15 @@ const initMCP = async (projectRoot, preselectedPlatform) => {
|
|
|
31
31
|
}))
|
|
32
32
|
})).platforms;
|
|
33
33
|
} catch {
|
|
34
|
-
|
|
34
|
+
p.cancel("Operation cancelled.");
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
if (!platform) {
|
|
39
|
-
|
|
39
|
+
p.cancel("Operation cancelled. No platform selected.");
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
|
-
const transport = await
|
|
42
|
+
const transport = await p.select({
|
|
43
43
|
message: "Which transport method do you want to use?",
|
|
44
44
|
options: [{
|
|
45
45
|
value: "stdio",
|
|
@@ -51,21 +51,21 @@ const initMCP = async (projectRoot, preselectedPlatform) => {
|
|
|
51
51
|
hint: "Hosted by Intlayer. Documentation only."
|
|
52
52
|
}]
|
|
53
53
|
});
|
|
54
|
-
if (
|
|
55
|
-
|
|
54
|
+
if (p.isCancel(transport) || !transport) {
|
|
55
|
+
p.cancel("Operation cancelled.");
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
const s =
|
|
58
|
+
const s = p.spinner();
|
|
59
59
|
s.start("Configuring MCP Server...");
|
|
60
60
|
try {
|
|
61
61
|
const result = await (0, _intlayer_engine_cli.installMCP)(root, platform, transport);
|
|
62
62
|
s.stop("MCP Server configured successfully");
|
|
63
|
-
|
|
63
|
+
p.note(result, "Success");
|
|
64
64
|
} catch (error) {
|
|
65
65
|
s.stop("Failed to configure MCP Server");
|
|
66
|
-
|
|
66
|
+
p.log.error(error instanceof Error ? error.message : String(error));
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
p.outro("Intlayer MCP Server initialization complete");
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
//#endregion
|
package/dist/cjs/initMCP.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initMCP.cjs","names":["findProjectRoot","resolve","getDetectedPlatform","PLATFORMS","PLATFORM_OPTIONS","
|
|
1
|
+
{"version":3,"file":"initMCP.cjs","names":["loadPrompts","findProjectRoot","resolve","getDetectedPlatform","PLATFORMS","PLATFORM_OPTIONS","installMCP"],"sources":["../../src/initMCP.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport {\n installMCP,\n type MCPTransport,\n PLATFORMS,\n type Platform,\n} from '@intlayer/engine/cli';\nimport enquirer from 'enquirer';\nimport { findProjectRoot } from './init';\nimport { getDetectedPlatform, PLATFORM_OPTIONS } from './initSkills';\nimport { loadPrompts } from './loadPrompts';\n\nexport const initMCP = async (\n projectRoot?: string,\n preselectedPlatform?: Platform\n) => {\n const p = await loadPrompts();\n\n const root = findProjectRoot(\n projectRoot ? resolve(projectRoot) : process.cwd()\n );\n\n p.intro('Initializing Intlayer MCP Server');\n\n let platform: Platform;\n\n if (preselectedPlatform) {\n platform = preselectedPlatform;\n } else {\n const detectedPlatform = getDetectedPlatform();\n\n try {\n const response = await enquirer.prompt<{ platforms: Platform }>({\n type: 'autocomplete',\n name: 'platforms',\n message: 'Which platform are you using? (Type to search)',\n multiple: false,\n initial: detectedPlatform\n ? PLATFORMS.indexOf(detectedPlatform)\n : undefined,\n choices: PLATFORM_OPTIONS.map((opt) => ({\n name: opt.value,\n message: opt.label,\n hint: opt.hint,\n })),\n });\n platform = response.platforms;\n } catch {\n p.cancel('Operation cancelled.');\n return;\n }\n }\n\n if (!platform) {\n p.cancel('Operation cancelled. No platform selected.');\n return;\n }\n\n const transport = (await p.select({\n message: 'Which transport method do you want to use?',\n options: [\n {\n value: 'stdio',\n label: 'Local server (stdio)',\n hint: 'Recommended. Integrates all features including CLI tools.',\n },\n {\n value: 'sse',\n label: 'Remote server (SSE)',\n hint: 'Hosted by Intlayer. Documentation only.',\n },\n ],\n })) as MCPTransport;\n\n if (p.isCancel(transport) || !transport) {\n p.cancel('Operation cancelled.');\n return;\n }\n\n const s = p.spinner();\n s.start('Configuring MCP Server...');\n\n try {\n const result = await installMCP(root, platform, transport);\n\n s.stop('MCP Server configured successfully');\n\n p.note(result, 'Success');\n } catch (error) {\n s.stop('Failed to configure MCP Server');\n p.log.error(error instanceof Error ? error.message : String(error));\n }\n\n p.outro('Intlayer MCP Server initialization complete');\n};\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,UAAU,OACrB,aACA,wBACG;CACH,MAAM,IAAI,MAAMA,gCAAY;CAE5B,MAAM,OAAOC,6BACX,kBAAcC,mBAAQ,WAAW,IAAI,QAAQ,IAAI,CACnD;CAEA,EAAE,MAAM,kCAAkC;CAE1C,IAAI;CAEJ,IAAI,qBACF,WAAW;MACN;EACL,MAAM,mBAAmBC,uCAAoB;EAE7C,IAAI;GAeF,YAAW,MAdY,iBAAS,OAAgC;IAC9D,MAAM;IACN,MAAM;IACN,SAAS;IACT,UAAU;IACV,SAAS,mBACLC,+BAAU,QAAQ,gBAAgB,IAClC;IACJ,SAASC,oCAAiB,KAAK,SAAS;KACtC,MAAM,IAAI;KACV,SAAS,IAAI;KACb,MAAM,IAAI;IACZ,EAAE;GACJ,CAAC,EACkB,CAAC;EACtB,QAAQ;GACN,EAAE,OAAO,sBAAsB;GAC/B;EACF;CACF;CAEA,IAAI,CAAC,UAAU;EACb,EAAE,OAAO,4CAA4C;EACrD;CACF;CAEA,MAAM,YAAa,MAAM,EAAE,OAAO;EAChC,SAAS;EACT,SAAS,CACP;GACE,OAAO;GACP,OAAO;GACP,MAAM;EACR,GACA;GACE,OAAO;GACP,OAAO;GACP,MAAM;EACR,CACF;CACF,CAAC;CAED,IAAI,EAAE,SAAS,SAAS,KAAK,CAAC,WAAW;EACvC,EAAE,OAAO,sBAAsB;EAC/B;CACF;CAEA,MAAM,IAAI,EAAE,QAAQ;CACpB,EAAE,MAAM,2BAA2B;CAEnC,IAAI;EACF,MAAM,SAAS,UAAMC,iCAAW,MAAM,UAAU,SAAS;EAEzD,EAAE,KAAK,oCAAoC;EAE3C,EAAE,KAAK,QAAQ,SAAS;CAC1B,SAAS,OAAO;EACd,EAAE,KAAK,gCAAgC;EACvC,EAAE,IAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;CACpE;CAEA,EAAE,MAAM,6CAA6C;AACvD"}
|
package/dist/cjs/initSkills.cjs
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_loadPrompts = require('./loadPrompts.cjs');
|
|
3
4
|
const require_init = require('./init.cjs');
|
|
4
5
|
let node_fs = require("node:fs");
|
|
5
6
|
let node_path = require("node:path");
|
|
6
7
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
7
8
|
let enquirer = require("enquirer");
|
|
8
9
|
enquirer = require_runtime.__toESM(enquirer);
|
|
9
|
-
let _clack_prompts = require("@clack/prompts");
|
|
10
|
-
_clack_prompts = require_runtime.__toESM(_clack_prompts);
|
|
11
10
|
|
|
12
11
|
//#region src/initSkills.ts
|
|
13
12
|
const PLATFORM_CHECKS = _intlayer_engine_cli.PLATFORMS.filter((platform) => _intlayer_engine_cli.PLATFORMS_METADATA[platform]?.check).map((platform) => ({
|
|
@@ -34,8 +33,9 @@ const getDependencies = (root) => {
|
|
|
34
33
|
}
|
|
35
34
|
};
|
|
36
35
|
const initSkills = async (projectRoot, preselectedPlatform) => {
|
|
36
|
+
const p = await require_loadPrompts.loadPrompts();
|
|
37
37
|
const root = require_init.findProjectRoot(projectRoot ? (0, node_path.resolve)(projectRoot) : process.cwd());
|
|
38
|
-
|
|
38
|
+
p.intro("Initializing Intlayer skills");
|
|
39
39
|
let platform;
|
|
40
40
|
if (preselectedPlatform) platform = preselectedPlatform;
|
|
41
41
|
else {
|
|
@@ -54,17 +54,17 @@ const initSkills = async (projectRoot, preselectedPlatform) => {
|
|
|
54
54
|
}))
|
|
55
55
|
})).platforms;
|
|
56
56
|
} catch {
|
|
57
|
-
|
|
57
|
+
p.cancel("Operation cancelled.");
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
if (!platform) {
|
|
62
|
-
|
|
62
|
+
p.log.warn("No platform selected. Nothing to install.");
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
const dependencies = getDependencies(root);
|
|
66
66
|
const initialValues = (0, _intlayer_engine_cli.getInitialSkills)(dependencies);
|
|
67
|
-
const selectedSkills = await
|
|
67
|
+
const selectedSkills = await p.multiselect({
|
|
68
68
|
message: "Select the documentation skills to provide to your AI:",
|
|
69
69
|
initialValues,
|
|
70
70
|
options: _intlayer_engine_cli.SKILLS.map((skill) => ({
|
|
@@ -74,21 +74,21 @@ const initSkills = async (projectRoot, preselectedPlatform) => {
|
|
|
74
74
|
})),
|
|
75
75
|
required: false
|
|
76
76
|
});
|
|
77
|
-
if (
|
|
78
|
-
|
|
77
|
+
if (p.isCancel(selectedSkills) || !selectedSkills || selectedSkills.length === 0) {
|
|
78
|
+
p.cancel("Operation cancelled. No skills selected.");
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
|
-
const s =
|
|
81
|
+
const s = p.spinner();
|
|
82
82
|
s.start("Installing skills...");
|
|
83
83
|
try {
|
|
84
84
|
const result = await (0, _intlayer_engine_cli.installSkills)(root, platform, selectedSkills);
|
|
85
85
|
s.stop("Skills installed successfully");
|
|
86
|
-
|
|
86
|
+
p.note(result, "Success");
|
|
87
87
|
} catch (error) {
|
|
88
88
|
s.stop("Failed to install skills");
|
|
89
|
-
|
|
89
|
+
p.log.error(error instanceof Error ? error.message : String(error));
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
p.outro("Intlayer skills initialization complete");
|
|
92
92
|
};
|
|
93
93
|
|
|
94
94
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initSkills.cjs","names":["PLATFORMS","PLATFORMS_METADATA","join","existsSync","readFileSync","findProjectRoot","resolve","getInitialSkills","
|
|
1
|
+
{"version":3,"file":"initSkills.cjs","names":["PLATFORMS","PLATFORMS_METADATA","join","existsSync","readFileSync","loadPrompts","findProjectRoot","resolve","getInitialSkills","SKILLS","SKILLS_METADATA","installSkills"],"sources":["../../src/initSkills.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport {\n getInitialSkills,\n installSkills,\n PLATFORMS,\n PLATFORMS_METADATA,\n type Platform,\n SKILLS,\n SKILLS_METADATA,\n} from '@intlayer/engine/cli';\nimport enquirer from 'enquirer';\nimport { findProjectRoot } from './init';\nimport { loadPrompts } from './loadPrompts';\n\nconst PLATFORM_CHECKS: Array<{ check: () => boolean; platform: Platform }> =\n PLATFORMS.filter((platform) => PLATFORMS_METADATA[platform]?.check).map(\n (platform) => ({\n check: PLATFORMS_METADATA[platform]?.check ?? (() => false),\n platform,\n })\n );\n\nexport const PLATFORM_OPTIONS: Array<{\n value: Platform;\n label: string;\n hint: string;\n}> = PLATFORMS.map((platform) => ({\n value: platform,\n label: PLATFORMS_METADATA[platform]?.label ?? '',\n hint: `(${PLATFORMS_METADATA[platform]?.dir})`,\n}));\n\nexport const getDetectedPlatform = (): Platform | undefined =>\n PLATFORM_CHECKS.find(({ check }) => check())?.platform;\n\nconst getDependencies = (root: string): Record<string, string> => {\n try {\n const packageJsonPath = join(root, 'package.json');\n if (!existsSync(packageJsonPath)) return {};\n\n const { dependencies = {}, devDependencies = {} } = JSON.parse(\n readFileSync(packageJsonPath, 'utf-8')\n );\n return { ...dependencies, ...devDependencies };\n } catch {\n return {};\n }\n};\n\nexport const initSkills = async (\n projectRoot?: string,\n preselectedPlatform?: Platform\n) => {\n const p = await loadPrompts();\n\n const root = findProjectRoot(\n projectRoot ? resolve(projectRoot) : process.cwd()\n );\n\n p.intro('Initializing Intlayer skills');\n\n let platform: Platform;\n\n if (preselectedPlatform) {\n platform = preselectedPlatform;\n } else {\n const detectedPlatform = getDetectedPlatform();\n\n try {\n const response = await enquirer.prompt<{ platforms: Platform }>({\n type: 'autocomplete',\n name: 'platforms',\n message: 'Which platforms are you using? (Type to search)',\n multiple: false,\n initial: detectedPlatform\n ? PLATFORMS.indexOf(detectedPlatform)\n : undefined,\n choices: PLATFORM_OPTIONS.map((opt) => ({\n name: opt.value,\n message: opt.label,\n hint: opt.hint,\n })),\n });\n platform = response.platforms;\n } catch {\n p.cancel('Operation cancelled.');\n return;\n }\n }\n\n if (!platform) {\n p.log.warn('No platform selected. Nothing to install.');\n return;\n }\n\n const dependencies = getDependencies(root);\n const initialValues = getInitialSkills(dependencies);\n\n const selectedSkills = await p.multiselect({\n message: 'Select the documentation skills to provide to your AI:',\n initialValues,\n options: SKILLS.map((skill) => ({\n value: skill,\n label: skill,\n hint: SKILLS_METADATA[skill],\n })),\n required: false,\n });\n\n if (\n p.isCancel(selectedSkills) ||\n !selectedSkills ||\n (selectedSkills as string[]).length === 0\n ) {\n p.cancel('Operation cancelled. No skills selected.');\n return;\n }\n\n const s = p.spinner();\n s.start('Installing skills...');\n\n try {\n const result = await installSkills(root, platform, selectedSkills);\n\n s.stop('Skills installed successfully');\n\n p.note(result, 'Success');\n } catch (error) {\n s.stop('Failed to install skills');\n p.log.error(error instanceof Error ? error.message : String(error));\n }\n\n p.outro('Intlayer skills initialization complete');\n};\n"],"mappings":";;;;;;;;;;;AAeA,MAAM,kBACJA,+BAAU,QAAQ,aAAaC,wCAAmB,SAAS,EAAE,KAAK,CAAC,CAAC,KACjE,cAAc;CACb,OAAOA,wCAAmB,SAAS,EAAE,gBAAgB;CACrD;AACF,EACF;AAEF,MAAa,mBAIRD,+BAAU,KAAK,cAAc;CAChC,OAAO;CACP,OAAOC,wCAAmB,SAAS,EAAE,SAAS;CAC9C,MAAM,IAAIA,wCAAmB,SAAS,EAAE,IAAI;AAC9C,EAAE;AAEF,MAAa,4BACX,gBAAgB,MAAM,EAAE,YAAY,MAAM,CAAC,CAAC,EAAE;AAEhD,MAAM,mBAAmB,SAAyC;CAChE,IAAI;EACF,MAAM,sBAAkBC,gBAAK,MAAM,cAAc;EACjD,IAAI,KAACC,oBAAW,eAAe,GAAG,OAAO,CAAC;EAE1C,MAAM,EAAE,eAAe,CAAC,GAAG,kBAAkB,CAAC,MAAM,KAAK,UACvDC,sBAAa,iBAAiB,OAAO,CACvC;EACA,OAAO;GAAE,GAAG;GAAc,GAAG;EAAgB;CAC/C,QAAQ;EACN,OAAO,CAAC;CACV;AACF;AAEA,MAAa,aAAa,OACxB,aACA,wBACG;CACH,MAAM,IAAI,MAAMC,gCAAY;CAE5B,MAAM,OAAOC,6BACX,kBAAcC,mBAAQ,WAAW,IAAI,QAAQ,IAAI,CACnD;CAEA,EAAE,MAAM,8BAA8B;CAEtC,IAAI;CAEJ,IAAI,qBACF,WAAW;MACN;EACL,MAAM,mBAAmB,oBAAoB;EAE7C,IAAI;GAeF,YAAW,MAdY,iBAAS,OAAgC;IAC9D,MAAM;IACN,MAAM;IACN,SAAS;IACT,UAAU;IACV,SAAS,mBACLP,+BAAU,QAAQ,gBAAgB,IAClC;IACJ,SAAS,iBAAiB,KAAK,SAAS;KACtC,MAAM,IAAI;KACV,SAAS,IAAI;KACb,MAAM,IAAI;IACZ,EAAE;GACJ,CAAC,EACkB,CAAC;EACtB,QAAQ;GACN,EAAE,OAAO,sBAAsB;GAC/B;EACF;CACF;CAEA,IAAI,CAAC,UAAU;EACb,EAAE,IAAI,KAAK,2CAA2C;EACtD;CACF;CAEA,MAAM,eAAe,gBAAgB,IAAI;CACzC,MAAM,oBAAgBQ,uCAAiB,YAAY;CAEnD,MAAM,iBAAiB,MAAM,EAAE,YAAY;EACzC,SAAS;EACT;EACA,SAASC,4BAAO,KAAK,WAAW;GAC9B,OAAO;GACP,OAAO;GACP,MAAMC,qCAAgB;EACxB,EAAE;EACF,UAAU;CACZ,CAAC;CAED,IACE,EAAE,SAAS,cAAc,KACzB,CAAC,kBACA,eAA4B,WAAW,GACxC;EACA,EAAE,OAAO,0CAA0C;EACnD;CACF;CAEA,MAAM,IAAI,EAAE,QAAQ;CACpB,EAAE,MAAM,sBAAsB;CAE9B,IAAI;EACF,MAAM,SAAS,UAAMC,oCAAc,MAAM,UAAU,cAAc;EAEjE,EAAE,KAAK,+BAA+B;EAEtC,EAAE,KAAK,QAAQ,SAAS;CAC1B,SAAS,OAAO;EACd,EAAE,KAAK,0BAA0B;EACjC,EAAE,IAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;CACpE;CAEA,EAAE,MAAM,yCAAyC;AACnD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
//#region src/loadPrompts.ts
|
|
3
|
+
/**
|
|
4
|
+
* Load the interactive prompt toolkit on demand.
|
|
5
|
+
*
|
|
6
|
+
* `@clack/prompts` must stay out of this package's static import graph:
|
|
7
|
+
* `@clack/core` imports `styleText` from `node:util`, which only exists from
|
|
8
|
+
* Node 20.12. A top-level import therefore fails to even parse the module graph
|
|
9
|
+
* on older runtimes, taking down every *non-interactive* consumer with it —
|
|
10
|
+
* notably the MCP server, which imports the CLI barrel but never prompts.
|
|
11
|
+
*
|
|
12
|
+
* @returns The `@clack/prompts` namespace.
|
|
13
|
+
*/
|
|
14
|
+
const loadPrompts = async () => await import("@clack/prompts");
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
exports.loadPrompts = loadPrompts;
|
|
18
|
+
//# sourceMappingURL=loadPrompts.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadPrompts.cjs","names":[],"sources":["../../src/loadPrompts.ts"],"sourcesContent":["/** The `@clack/prompts` module namespace, resolved on demand. */\nexport type Prompts = typeof import('@clack/prompts');\n\n/**\n * Load the interactive prompt toolkit on demand.\n *\n * `@clack/prompts` must stay out of this package's static import graph:\n * `@clack/core` imports `styleText` from `node:util`, which only exists from\n * Node 20.12. A top-level import therefore fails to even parse the module graph\n * on older runtimes, taking down every *non-interactive* consumer with it —\n * notably the MCP server, which imports the CLI barrel but never prompts.\n *\n * @returns The `@clack/prompts` namespace.\n */\nexport const loadPrompts = async (): Promise<Prompts> =>\n await import('@clack/prompts');\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAa,cAAc,YACzB,MAAM,OAAO"}
|
package/dist/cjs/push/push.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_loadPrompts = require('../loadPrompts.cjs');
|
|
3
4
|
const require_utils_checkAccess = require('../utils/checkAccess.cjs');
|
|
4
5
|
const require_utils_selectCmsEnvironment = require('../utils/selectCmsEnvironment.cjs');
|
|
5
6
|
const require_pushLog = require('../pushLog.cjs');
|
|
@@ -165,7 +166,7 @@ const push = async (options) => {
|
|
|
165
166
|
const remoteDictionaries = successfullyPushedDictionaries.filter((dictionary) => dictionary.location === "remote");
|
|
166
167
|
const remoteDictionariesKeys = remoteDictionaries.map((dictionary) => dictionary.key);
|
|
167
168
|
if (remoteDictionaries.length > 0) {
|
|
168
|
-
const { confirm, isCancel } = await
|
|
169
|
+
const { confirm, isCancel } = await require_loadPrompts.loadPrompts();
|
|
169
170
|
const shouldDelete = await confirm({
|
|
170
171
|
message: `Do you want to delete the local dictionaries that were successfully pushed? ${(0, _intlayer_config_logger.colorize)("(Dictionaries:", _intlayer_config_colors.GREY, _intlayer_config_colors.RESET)} ${(0, _intlayer_config_logger.colorizeKey)(remoteDictionariesKeys)}${(0, _intlayer_config_logger.colorize)(")", _intlayer_config_colors.GREY, _intlayer_config_colors.RESET)}`,
|
|
171
172
|
initialValue: false
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.cjs","names":["ANSIColors","getConfiguration","getAppLogger","prepareIntlayer","checkCMSAuth","getAuthenticatedAPI","selectCmsEnvironment","getUnmergedDictionaries","colorize","listGitFiles","join","PushLogger","writeContentDeclaration","parallelize","colorizeKey","fsPromises","formatPath"],"sources":["../../../src/push/push.ts"],"sourcesContent":["import * as fsPromises from 'node:fs/promises';\nimport { join } from 'node:path';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport {\n prepareIntlayer,\n writeContentDeclaration,\n} from '@intlayer/engine/build';\nimport {\n type ListGitFilesOptions,\n listGitFiles,\n logConfigDetails,\n} from '@intlayer/engine/cli';\nimport { formatPath, parallelize } from '@intlayer/engine/utils';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { PushLogger, type PushStatus } from '../pushLog';\nimport { checkCMSAuth, getAuthenticatedAPI } from '../utils/checkAccess';\nimport { selectCmsEnvironment } from '../utils/selectCmsEnvironment';\n\ntype PushOptions = {\n deleteLocaleDictionary?: boolean;\n keepLocaleDictionary?: boolean;\n dictionaries?: string[];\n gitOptions?: ListGitFilesOptions;\n configOptions?: GetConfigurationOptions;\n build?: boolean;\n};\n\ntype DictionariesStatus = {\n dictionary: Dictionary;\n status:\n | 'pending'\n | 'pushing'\n | 'modified'\n | 'pushed'\n | 'up-to-date'\n | 'unknown'\n | 'error';\n error?: Error;\n errorMessage?: string;\n};\n\n// Print per-dictionary summary similar to loadDictionaries\nconst statusIconsAndColors = {\n pushed: { icon: '✔', color: ANSIColors.GREEN },\n modified: { icon: '✔', color: ANSIColors.GREEN },\n 'up-to-date': { icon: '=', color: ANSIColors.GREY },\n error: { icon: '✖', color: ANSIColors.RED },\n default: { icon: '⏲', color: ANSIColors.BLUE },\n};\n\nconst getIconAndColor = (status: DictionariesStatus['status']) => {\n return (\n statusIconsAndColors[status as keyof typeof statusIconsAndColors] ??\n statusIconsAndColors.default\n );\n};\n\n/**\n * Get all local dictionaries and push them simultaneously.\n */\nexport const push = async (options?: PushOptions): Promise<void> => {\n const config = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(config);\n\n if (options?.build === true) {\n await prepareIntlayer(config, { forceRun: true });\n } else if (typeof options?.build === 'undefined') {\n await prepareIntlayer(config);\n }\n\n try {\n const hasCMSAuth = await checkCMSAuth(config);\n\n if (!hasCMSAuth) return;\n\n const intlayerAPI = await getAuthenticatedAPI(config);\n\n await selectCmsEnvironment(\n options?.configOptions?.env,\n intlayerAPI,\n config\n );\n\n const unmergedDictionariesRecord = getUnmergedDictionaries(config);\n const allDictionaries = Object.values(unmergedDictionariesRecord).flat();\n\n const customLocations = Array.from(\n new Set(\n allDictionaries\n .map((dictionary) => dictionary.location)\n .filter(\n (location) =>\n location && !['remote', 'local', 'hybrid'].includes(location)\n )\n )\n ) as string[];\n\n // Include all custom locations automatically — no interactive prompt needed.\n const selectedCustomLocations: string[] = customLocations;\n\n let dictionaries: Dictionary[] = allDictionaries.filter((dictionary) => {\n const location =\n dictionary.location ?? config.dictionary?.location ?? 'local';\n\n return (\n location === 'remote' ||\n location === 'hybrid' ||\n selectedCustomLocations.includes(location)\n );\n });\n\n // Check if the dictionaries list is empty after filtering by location\n if (dictionaries.length === 0) {\n appLogger(\n `No dictionaries found to push. Only dictionaries with location ${colorize('remote', ANSIColors.BLUE, ANSIColors.RESET)}, ${colorize('hybrid', ANSIColors.BLUE, ANSIColors.RESET)} or selected custom locations are pushed.`,\n { level: 'warn' }\n );\n appLogger(\n `You can set the location in your dictionary file (e.g. ${colorize(\"{ key: 'my-key', location: 'hybrid', ... }\", ANSIColors.BLUE, ANSIColors.RESET)} or globally in your intlayer.config.ts file (e.g. ${colorize(\"{ dictionary: { location: 'hybrid' } }\", ANSIColors.BLUE, ANSIColors.RESET)}).`,\n { level: 'info' }\n );\n return;\n }\n\n const existingDictionariesKeys: string[] = Object.keys(\n unmergedDictionariesRecord\n );\n\n if (options?.dictionaries) {\n // Check if the provided dictionaries exist\n const noneExistingDictionariesOption = options.dictionaries.filter(\n (dictionaryId) => !existingDictionariesKeys.includes(dictionaryId)\n );\n\n if (noneExistingDictionariesOption.length > 0) {\n appLogger(\n `The following dictionaries do not exist: ${noneExistingDictionariesOption.join(\n ', '\n )} and have been ignored.`,\n {\n level: 'error',\n }\n );\n }\n\n // Filter the dictionaries from the provided list of IDs\n dictionaries = dictionaries.filter((dictionary) =>\n options.dictionaries?.includes(dictionary.key)\n );\n }\n\n if (options?.gitOptions) {\n const gitFiles = await listGitFiles(options.gitOptions);\n\n dictionaries = dictionaries.filter((dictionary) =>\n gitFiles.includes(\n join(config.system.baseDir, dictionary.filePath ?? '')\n )\n );\n }\n\n // Check if the dictionaries list is empty\n if (dictionaries.length === 0) {\n appLogger('No local dictionaries found', {\n level: 'error',\n });\n return;\n }\n\n appLogger('Pushing dictionaries:');\n\n // Prepare dictionaries statuses\n const dictionariesStatuses: DictionariesStatus[] = dictionaries.map(\n (dictionary) => ({\n dictionary,\n status: 'pending',\n })\n );\n\n // Initialize aggregated logger similar to loadDictionaries\n const logger = new PushLogger();\n logger.update(\n dictionariesStatuses.map<PushStatus>((s) => ({\n dictionaryKey: s.dictionary.key,\n status: 'pending',\n }))\n );\n\n const successfullyPushedDictionaries: Dictionary[] = [];\n\n const processDictionary = async (\n statusObj: DictionariesStatus\n ): Promise<void> => {\n statusObj.status = 'pushing';\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'pushing' },\n ]);\n\n try {\n const pushResult = await intlayerAPI.dictionary.pushDictionaries([\n statusObj.dictionary,\n ]);\n\n const updatedDictionaries = pushResult.data?.updatedDictionaries ?? [];\n const newDictionaries = pushResult.data?.newDictionaries ?? [];\n const upToDateDictionaries =\n pushResult.data?.upToDateDictionaries ?? [];\n\n const allDictionaries = [\n ...updatedDictionaries,\n ...newDictionaries,\n ...upToDateDictionaries,\n ];\n\n for (const remoteDictionaryData of allDictionaries) {\n const localDictionary = unmergedDictionariesRecord[\n remoteDictionaryData.key\n ]?.find(\n (dictionary) => dictionary.localId === remoteDictionaryData.localId\n );\n\n if (!localDictionary) continue;\n\n await writeContentDeclaration(\n { ...localDictionary, id: remoteDictionaryData.id },\n config\n );\n }\n\n if (\n updatedDictionaries.some(\n (dictionary) => dictionary.key === statusObj.dictionary.key\n )\n ) {\n statusObj.status = 'modified';\n successfullyPushedDictionaries.push(statusObj.dictionary);\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'modified' },\n ]);\n } else if (\n newDictionaries.some(\n (dictionary) => dictionary.key === statusObj.dictionary.key\n )\n ) {\n statusObj.status = 'pushed';\n successfullyPushedDictionaries.push(statusObj.dictionary);\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'pushed' },\n ]);\n } else if (\n upToDateDictionaries.some(\n (dictionary) => dictionary.key === statusObj.dictionary.key\n )\n ) {\n statusObj.status = 'up-to-date';\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'up-to-date' },\n ]);\n } else {\n statusObj.status = 'unknown';\n }\n } catch (error) {\n statusObj.status = 'error';\n statusObj.error = error as Error;\n statusObj.errorMessage = `Error pushing dictionary ${statusObj.dictionary.key}: ${error}`;\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'error' },\n ]);\n }\n };\n\n // Process dictionaries in parallel with a concurrency limit (reuse parallelize)\n await parallelize(dictionariesStatuses, processDictionary, 5);\n\n // Stop the logger and render final state\n logger.finish();\n\n for (const dictionaryStatus of dictionariesStatuses) {\n const { icon, color } = getIconAndColor(dictionaryStatus.status);\n appLogger(\n ` - ${colorizeKey(dictionaryStatus.dictionary.key)} ${ANSIColors.GREY}[${color}${icon} ${dictionaryStatus.status}${ANSIColors.GREY}]${ANSIColors.RESET}`\n );\n }\n\n // Output any error messages\n for (const statusObj of dictionariesStatuses) {\n if (statusObj.errorMessage) {\n appLogger(statusObj.errorMessage, {\n level: 'error',\n });\n }\n }\n\n // Handle delete or keep options\n const deleteOption = options?.deleteLocaleDictionary;\n const keepOption = options?.keepLocaleDictionary;\n\n if (deleteOption && keepOption) {\n throw new Error(\n 'Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.'\n );\n }\n\n if (deleteOption) {\n // Delete only the successfully pushed dictionaries\n await deleteLocalDictionaries(successfullyPushedDictionaries, options);\n } else if (keepOption) {\n // Do nothing, keep the local dictionaries\n } else {\n // Ask the user\n const remoteDictionaries = successfullyPushedDictionaries.filter(\n (dictionary) => dictionary.location === 'remote'\n );\n const remoteDictionariesKeys = remoteDictionaries.map(\n (dictionary) => dictionary.key\n );\n\n if (remoteDictionaries.length > 0) {\n const { confirm, isCancel } = await import('@clack/prompts');\n\n const shouldDelete = await confirm({\n message: `Do you want to delete the local dictionaries that were successfully pushed? ${colorize('(Dictionaries:', ANSIColors.GREY, ANSIColors.RESET)} ${colorizeKey(remoteDictionariesKeys)}${colorize(')', ANSIColors.GREY, ANSIColors.RESET)}`,\n initialValue: false,\n });\n\n if (isCancel(shouldDelete)) {\n return;\n }\n\n if (shouldDelete) {\n await deleteLocalDictionaries(remoteDictionaries, options);\n }\n }\n }\n } catch (error) {\n appLogger(error, {\n level: 'error',\n });\n }\n};\n\nconst deleteLocalDictionaries = async (\n dictionariesToDelete: Dictionary[],\n options?: PushOptions\n): Promise<void> => {\n const config = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(config);\n\n // Use a Set to collect all unique file paths\n const filePathsSet: Set<string> = new Set();\n\n for (const dictionary of dictionariesToDelete) {\n const { filePath } = dictionary;\n\n if (!filePath) {\n appLogger(\n `Dictionary ${colorizeKey(dictionary.key)} does not have a file path`,\n {\n level: 'error',\n }\n );\n continue;\n }\n\n filePathsSet.add(filePath);\n }\n\n for (const filePath of filePathsSet) {\n try {\n const stats = await fsPromises.lstat(filePath);\n\n if (stats.isFile()) {\n await fsPromises.unlink(filePath);\n appLogger(`Deleted file ${formatPath(filePath)}`, {});\n } else if (stats.isDirectory()) {\n appLogger(`Path is a directory ${formatPath(filePath)}, skipping.`, {});\n } else {\n appLogger(\n `Unknown file type for ${formatPath(filePath)}, skipping.`,\n {}\n );\n }\n } catch (err) {\n appLogger(`Error deleting ${formatPath(filePath)}: ${err}`, {\n level: 'error',\n });\n }\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgDA,MAAM,uBAAuB;CAC3B,QAAQ;EAAE,MAAM;EAAK,OAAOA,wBAAW;CAAM;CAC7C,UAAU;EAAE,MAAM;EAAK,OAAOA,wBAAW;CAAM;CAC/C,cAAc;EAAE,MAAM;EAAK,OAAOA,wBAAW;CAAK;CAClD,OAAO;EAAE,MAAM;EAAK,OAAOA,wBAAW;CAAI;CAC1C,SAAS;EAAE,MAAM;EAAK,OAAOA,wBAAW;CAAK;AAC/C;AAEA,MAAM,mBAAmB,WAAyC;CAChE,OACE,qBAAqB,WACrB,qBAAqB;AAEzB;;;;AAKA,MAAa,OAAO,OAAO,YAAyC;CAClE,MAAM,aAASC,wCAAiB,SAAS,aAAa;CACtD,2CAAiB,SAAS,aAAa;CAEvC,MAAM,gBAAYC,sCAAa,MAAM;CAErC,IAAI,SAAS,UAAU,MACrB,UAAMC,wCAAgB,QAAQ,EAAE,UAAU,KAAK,CAAC;MAC3C,IAAI,OAAO,SAAS,UAAU,aACnC,UAAMA,wCAAgB,MAAM;CAG9B,IAAI;EAGF,IAAI,CAAC,MAFoBC,uCAAa,MAAM,GAE3B;EAEjB,MAAM,cAAc,MAAMC,8CAAoB,MAAM;EAEpD,MAAMC,wDACJ,SAAS,eAAe,KACxB,aACA,MACF;EAEA,MAAM,iCAA6BC,+DAAwB,MAAM;EACjE,MAAM,kBAAkB,OAAO,OAAO,0BAA0B,CAAC,CAAC,KAAK;EAcvE,MAAM,0BAZkB,MAAM,KAC5B,IAAI,IACF,gBACG,KAAK,eAAe,WAAW,QAAQ,CAAC,CACxC,QACE,aACC,YAAY,CAAC;GAAC;GAAU;GAAS;EAAQ,CAAC,CAAC,SAAS,QAAQ,CAChE,CACJ,CAIsD;EAExD,IAAI,eAA6B,gBAAgB,QAAQ,eAAe;GACtE,MAAM,WACJ,WAAW,YAAY,OAAO,YAAY,YAAY;GAExD,OACE,aAAa,YACb,aAAa,YACb,wBAAwB,SAAS,QAAQ;EAE7C,CAAC;EAGD,IAAI,aAAa,WAAW,GAAG;GAC7B,UACE,sEAAkEC,kCAAS,UAAUR,wBAAW,MAAMA,wBAAW,KAAK,EAAE,QAAIQ,kCAAS,UAAUR,wBAAW,MAAMA,wBAAW,KAAK,EAAE,4CAClL,EAAE,OAAO,OAAO,CAClB;GACA,UACE,8DAA0DQ,kCAAS,8CAA8CR,wBAAW,MAAMA,wBAAW,KAAK,EAAE,yDAAqDQ,kCAAS,0CAA0CR,wBAAW,MAAMA,wBAAW,KAAK,EAAE,KAC/R,EAAE,OAAO,OAAO,CAClB;GACA;EACF;EAEA,MAAM,2BAAqC,OAAO,KAChD,0BACF;EAEA,IAAI,SAAS,cAAc;GAEzB,MAAM,iCAAiC,QAAQ,aAAa,QACzD,iBAAiB,CAAC,yBAAyB,SAAS,YAAY,CACnE;GAEA,IAAI,+BAA+B,SAAS,GAC1C,UACE,4CAA4C,+BAA+B,KACzE,IACF,EAAE,0BACF,EACE,OAAO,QACT,CACF;GAIF,eAAe,aAAa,QAAQ,eAClC,QAAQ,cAAc,SAAS,WAAW,GAAG,CAC/C;EACF;EAEA,IAAI,SAAS,YAAY;GACvB,MAAM,WAAW,UAAMS,mCAAa,QAAQ,UAAU;GAEtD,eAAe,aAAa,QAAQ,eAClC,SAAS,aACPC,gBAAK,OAAO,OAAO,SAAS,WAAW,YAAY,EAAE,CACvD,CACF;EACF;EAGA,IAAI,aAAa,WAAW,GAAG;GAC7B,UAAU,+BAA+B,EACvC,OAAO,QACT,CAAC;GACD;EACF;EAEA,UAAU,uBAAuB;EAGjC,MAAM,uBAA6C,aAAa,KAC7D,gBAAgB;GACf;GACA,QAAQ;EACV,EACF;EAGA,MAAM,SAAS,IAAIC,2BAAW;EAC9B,OAAO,OACL,qBAAqB,KAAiB,OAAO;GAC3C,eAAe,EAAE,WAAW;GAC5B,QAAQ;EACV,EAAE,CACJ;EAEA,MAAM,iCAA+C,CAAC;EAEtD,MAAM,oBAAoB,OACxB,cACkB;GAClB,UAAU,SAAS;GACnB,OAAO,OAAO,CACZ;IAAE,eAAe,UAAU,WAAW;IAAK,QAAQ;GAAU,CAC/D,CAAC;GAED,IAAI;IACF,MAAM,aAAa,MAAM,YAAY,WAAW,iBAAiB,CAC/D,UAAU,UACZ,CAAC;IAED,MAAM,sBAAsB,WAAW,MAAM,uBAAuB,CAAC;IACrE,MAAM,kBAAkB,WAAW,MAAM,mBAAmB,CAAC;IAC7D,MAAM,uBACJ,WAAW,MAAM,wBAAwB,CAAC;IAE5C,MAAM,kBAAkB;KACtB,GAAG;KACH,GAAG;KACH,GAAG;IACL;IAEA,KAAK,MAAM,wBAAwB,iBAAiB;KAClD,MAAM,kBAAkB,2BACtB,qBAAqB,IACtB,EAAE,MACA,eAAe,WAAW,YAAY,qBAAqB,OAC9D;KAEA,IAAI,CAAC,iBAAiB;KAEtB,UAAMC,gDACJ;MAAE,GAAG;MAAiB,IAAI,qBAAqB;KAAG,GAClD,MACF;IACF;IAEA,IACE,oBAAoB,MACjB,eAAe,WAAW,QAAQ,UAAU,WAAW,GAC1D,GACA;KACA,UAAU,SAAS;KACnB,+BAA+B,KAAK,UAAU,UAAU;KACxD,OAAO,OAAO,CACZ;MAAE,eAAe,UAAU,WAAW;MAAK,QAAQ;KAAW,CAChE,CAAC;IACH,OAAO,IACL,gBAAgB,MACb,eAAe,WAAW,QAAQ,UAAU,WAAW,GAC1D,GACA;KACA,UAAU,SAAS;KACnB,+BAA+B,KAAK,UAAU,UAAU;KACxD,OAAO,OAAO,CACZ;MAAE,eAAe,UAAU,WAAW;MAAK,QAAQ;KAAS,CAC9D,CAAC;IACH,OAAO,IACL,qBAAqB,MAClB,eAAe,WAAW,QAAQ,UAAU,WAAW,GAC1D,GACA;KACA,UAAU,SAAS;KACnB,OAAO,OAAO,CACZ;MAAE,eAAe,UAAU,WAAW;MAAK,QAAQ;KAAa,CAClE,CAAC;IACH,OACE,UAAU,SAAS;GAEvB,SAAS,OAAO;IACd,UAAU,SAAS;IACnB,UAAU,QAAQ;IAClB,UAAU,eAAe,4BAA4B,UAAU,WAAW,IAAI,IAAI;IAClF,OAAO,OAAO,CACZ;KAAE,eAAe,UAAU,WAAW;KAAK,QAAQ;IAAQ,CAC7D,CAAC;GACH;EACF;EAGA,UAAMC,oCAAY,sBAAsB,mBAAmB,CAAC;EAG5D,OAAO,OAAO;EAEd,KAAK,MAAM,oBAAoB,sBAAsB;GACnD,MAAM,EAAE,MAAM,UAAU,gBAAgB,iBAAiB,MAAM;GAC/D,UACE,UAAMC,qCAAY,iBAAiB,WAAW,GAAG,EAAE,GAAGd,wBAAW,KAAK,GAAG,QAAQ,KAAK,GAAG,iBAAiB,SAASA,wBAAW,KAAK,GAAGA,wBAAW,OACnJ;EACF;EAGA,KAAK,MAAM,aAAa,sBACtB,IAAI,UAAU,cACZ,UAAU,UAAU,cAAc,EAChC,OAAO,QACT,CAAC;EAKL,MAAM,eAAe,SAAS;EAC9B,MAAM,aAAa,SAAS;EAE5B,IAAI,gBAAgB,YAClB,MAAM,IAAI,MACR,kFACF;EAGF,IAAI,cAEF,MAAM,wBAAwB,gCAAgC,OAAO;OAChE,IAAI,YAAY,CAEvB,OAAO;GAEL,MAAM,qBAAqB,+BAA+B,QACvD,eAAe,WAAW,aAAa,QAC1C;GACA,MAAM,yBAAyB,mBAAmB,KAC/C,eAAe,WAAW,GAC7B;GAEA,IAAI,mBAAmB,SAAS,GAAG;IACjC,MAAM,EAAE,SAAS,aAAa,MAAM,OAAO;IAE3C,MAAM,eAAe,MAAM,QAAQ;KACjC,SAAS,mFAA+EQ,kCAAS,kBAAkBR,wBAAW,MAAMA,wBAAW,KAAK,EAAE,OAAGc,qCAAY,sBAAsB,QAAIN,kCAAS,KAAKR,wBAAW,MAAMA,wBAAW,KAAK;KAC9O,cAAc;IAChB,CAAC;IAED,IAAI,SAAS,YAAY,GACvB;IAGF,IAAI,cACF,MAAM,wBAAwB,oBAAoB,OAAO;GAE7D;EACF;CACF,SAAS,OAAO;EACd,UAAU,OAAO,EACf,OAAO,QACT,CAAC;CACH;AACF;AAEA,MAAM,0BAA0B,OAC9B,sBACA,YACkB;CAClB,MAAM,aAASC,wCAAiB,SAAS,aAAa;CACtD,MAAM,gBAAYC,sCAAa,MAAM;CAGrC,MAAM,+BAA4B,IAAI,IAAI;CAE1C,KAAK,MAAM,cAAc,sBAAsB;EAC7C,MAAM,EAAE,aAAa;EAErB,IAAI,CAAC,UAAU;GACb,UACE,kBAAcY,qCAAY,WAAW,GAAG,EAAE,6BAC1C,EACE,OAAO,QACT,CACF;GACA;EACF;EAEA,aAAa,IAAI,QAAQ;CAC3B;CAEA,KAAK,MAAM,YAAY,cACrB,IAAI;EACF,MAAM,QAAQ,MAAMC,iBAAW,MAAM,QAAQ;EAE7C,IAAI,MAAM,OAAO,GAAG;GAClB,MAAMA,iBAAW,OAAO,QAAQ;GAChC,UAAU,oBAAgBC,mCAAW,QAAQ,KAAK,CAAC,CAAC;EACtD,OAAO,IAAI,MAAM,YAAY,GAC3B,UAAU,2BAAuBA,mCAAW,QAAQ,EAAE,cAAc,CAAC,CAAC;OAEtE,UACE,6BAAyBA,mCAAW,QAAQ,EAAE,cAC9C,CAAC,CACH;CAEJ,SAAS,KAAK;EACZ,UAAU,sBAAkBA,mCAAW,QAAQ,EAAE,IAAI,OAAO,EAC1D,OAAO,QACT,CAAC;CACH;AAEJ"}
|
|
1
|
+
{"version":3,"file":"push.cjs","names":["ANSIColors","getConfiguration","getAppLogger","prepareIntlayer","checkCMSAuth","getAuthenticatedAPI","selectCmsEnvironment","getUnmergedDictionaries","colorize","listGitFiles","join","PushLogger","writeContentDeclaration","parallelize","colorizeKey","loadPrompts","fsPromises","formatPath"],"sources":["../../../src/push/push.ts"],"sourcesContent":["import * as fsPromises from 'node:fs/promises';\nimport { join } from 'node:path';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport {\n prepareIntlayer,\n writeContentDeclaration,\n} from '@intlayer/engine/build';\nimport {\n type ListGitFilesOptions,\n listGitFiles,\n logConfigDetails,\n} from '@intlayer/engine/cli';\nimport { formatPath, parallelize } from '@intlayer/engine/utils';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { loadPrompts } from '../loadPrompts';\nimport { PushLogger, type PushStatus } from '../pushLog';\nimport { checkCMSAuth, getAuthenticatedAPI } from '../utils/checkAccess';\nimport { selectCmsEnvironment } from '../utils/selectCmsEnvironment';\n\ntype PushOptions = {\n deleteLocaleDictionary?: boolean;\n keepLocaleDictionary?: boolean;\n dictionaries?: string[];\n gitOptions?: ListGitFilesOptions;\n configOptions?: GetConfigurationOptions;\n build?: boolean;\n};\n\ntype DictionariesStatus = {\n dictionary: Dictionary;\n status:\n | 'pending'\n | 'pushing'\n | 'modified'\n | 'pushed'\n | 'up-to-date'\n | 'unknown'\n | 'error';\n error?: Error;\n errorMessage?: string;\n};\n\n// Print per-dictionary summary similar to loadDictionaries\nconst statusIconsAndColors = {\n pushed: { icon: '✔', color: ANSIColors.GREEN },\n modified: { icon: '✔', color: ANSIColors.GREEN },\n 'up-to-date': { icon: '=', color: ANSIColors.GREY },\n error: { icon: '✖', color: ANSIColors.RED },\n default: { icon: '⏲', color: ANSIColors.BLUE },\n};\n\nconst getIconAndColor = (status: DictionariesStatus['status']) => {\n return (\n statusIconsAndColors[status as keyof typeof statusIconsAndColors] ??\n statusIconsAndColors.default\n );\n};\n\n/**\n * Get all local dictionaries and push them simultaneously.\n */\nexport const push = async (options?: PushOptions): Promise<void> => {\n const config = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(config);\n\n if (options?.build === true) {\n await prepareIntlayer(config, { forceRun: true });\n } else if (typeof options?.build === 'undefined') {\n await prepareIntlayer(config);\n }\n\n try {\n const hasCMSAuth = await checkCMSAuth(config);\n\n if (!hasCMSAuth) return;\n\n const intlayerAPI = await getAuthenticatedAPI(config);\n\n await selectCmsEnvironment(\n options?.configOptions?.env,\n intlayerAPI,\n config\n );\n\n const unmergedDictionariesRecord = getUnmergedDictionaries(config);\n const allDictionaries = Object.values(unmergedDictionariesRecord).flat();\n\n const customLocations = Array.from(\n new Set(\n allDictionaries\n .map((dictionary) => dictionary.location)\n .filter(\n (location) =>\n location && !['remote', 'local', 'hybrid'].includes(location)\n )\n )\n ) as string[];\n\n // Include all custom locations automatically — no interactive prompt needed.\n const selectedCustomLocations: string[] = customLocations;\n\n let dictionaries: Dictionary[] = allDictionaries.filter((dictionary) => {\n const location =\n dictionary.location ?? config.dictionary?.location ?? 'local';\n\n return (\n location === 'remote' ||\n location === 'hybrid' ||\n selectedCustomLocations.includes(location)\n );\n });\n\n // Check if the dictionaries list is empty after filtering by location\n if (dictionaries.length === 0) {\n appLogger(\n `No dictionaries found to push. Only dictionaries with location ${colorize('remote', ANSIColors.BLUE, ANSIColors.RESET)}, ${colorize('hybrid', ANSIColors.BLUE, ANSIColors.RESET)} or selected custom locations are pushed.`,\n { level: 'warn' }\n );\n appLogger(\n `You can set the location in your dictionary file (e.g. ${colorize(\"{ key: 'my-key', location: 'hybrid', ... }\", ANSIColors.BLUE, ANSIColors.RESET)} or globally in your intlayer.config.ts file (e.g. ${colorize(\"{ dictionary: { location: 'hybrid' } }\", ANSIColors.BLUE, ANSIColors.RESET)}).`,\n { level: 'info' }\n );\n return;\n }\n\n const existingDictionariesKeys: string[] = Object.keys(\n unmergedDictionariesRecord\n );\n\n if (options?.dictionaries) {\n // Check if the provided dictionaries exist\n const noneExistingDictionariesOption = options.dictionaries.filter(\n (dictionaryId) => !existingDictionariesKeys.includes(dictionaryId)\n );\n\n if (noneExistingDictionariesOption.length > 0) {\n appLogger(\n `The following dictionaries do not exist: ${noneExistingDictionariesOption.join(\n ', '\n )} and have been ignored.`,\n {\n level: 'error',\n }\n );\n }\n\n // Filter the dictionaries from the provided list of IDs\n dictionaries = dictionaries.filter((dictionary) =>\n options.dictionaries?.includes(dictionary.key)\n );\n }\n\n if (options?.gitOptions) {\n const gitFiles = await listGitFiles(options.gitOptions);\n\n dictionaries = dictionaries.filter((dictionary) =>\n gitFiles.includes(\n join(config.system.baseDir, dictionary.filePath ?? '')\n )\n );\n }\n\n // Check if the dictionaries list is empty\n if (dictionaries.length === 0) {\n appLogger('No local dictionaries found', {\n level: 'error',\n });\n return;\n }\n\n appLogger('Pushing dictionaries:');\n\n // Prepare dictionaries statuses\n const dictionariesStatuses: DictionariesStatus[] = dictionaries.map(\n (dictionary) => ({\n dictionary,\n status: 'pending',\n })\n );\n\n // Initialize aggregated logger similar to loadDictionaries\n const logger = new PushLogger();\n logger.update(\n dictionariesStatuses.map<PushStatus>((s) => ({\n dictionaryKey: s.dictionary.key,\n status: 'pending',\n }))\n );\n\n const successfullyPushedDictionaries: Dictionary[] = [];\n\n const processDictionary = async (\n statusObj: DictionariesStatus\n ): Promise<void> => {\n statusObj.status = 'pushing';\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'pushing' },\n ]);\n\n try {\n const pushResult = await intlayerAPI.dictionary.pushDictionaries([\n statusObj.dictionary,\n ]);\n\n const updatedDictionaries = pushResult.data?.updatedDictionaries ?? [];\n const newDictionaries = pushResult.data?.newDictionaries ?? [];\n const upToDateDictionaries =\n pushResult.data?.upToDateDictionaries ?? [];\n\n const allDictionaries = [\n ...updatedDictionaries,\n ...newDictionaries,\n ...upToDateDictionaries,\n ];\n\n for (const remoteDictionaryData of allDictionaries) {\n const localDictionary = unmergedDictionariesRecord[\n remoteDictionaryData.key\n ]?.find(\n (dictionary) => dictionary.localId === remoteDictionaryData.localId\n );\n\n if (!localDictionary) continue;\n\n await writeContentDeclaration(\n { ...localDictionary, id: remoteDictionaryData.id },\n config\n );\n }\n\n if (\n updatedDictionaries.some(\n (dictionary) => dictionary.key === statusObj.dictionary.key\n )\n ) {\n statusObj.status = 'modified';\n successfullyPushedDictionaries.push(statusObj.dictionary);\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'modified' },\n ]);\n } else if (\n newDictionaries.some(\n (dictionary) => dictionary.key === statusObj.dictionary.key\n )\n ) {\n statusObj.status = 'pushed';\n successfullyPushedDictionaries.push(statusObj.dictionary);\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'pushed' },\n ]);\n } else if (\n upToDateDictionaries.some(\n (dictionary) => dictionary.key === statusObj.dictionary.key\n )\n ) {\n statusObj.status = 'up-to-date';\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'up-to-date' },\n ]);\n } else {\n statusObj.status = 'unknown';\n }\n } catch (error) {\n statusObj.status = 'error';\n statusObj.error = error as Error;\n statusObj.errorMessage = `Error pushing dictionary ${statusObj.dictionary.key}: ${error}`;\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'error' },\n ]);\n }\n };\n\n // Process dictionaries in parallel with a concurrency limit (reuse parallelize)\n await parallelize(dictionariesStatuses, processDictionary, 5);\n\n // Stop the logger and render final state\n logger.finish();\n\n for (const dictionaryStatus of dictionariesStatuses) {\n const { icon, color } = getIconAndColor(dictionaryStatus.status);\n appLogger(\n ` - ${colorizeKey(dictionaryStatus.dictionary.key)} ${ANSIColors.GREY}[${color}${icon} ${dictionaryStatus.status}${ANSIColors.GREY}]${ANSIColors.RESET}`\n );\n }\n\n // Output any error messages\n for (const statusObj of dictionariesStatuses) {\n if (statusObj.errorMessage) {\n appLogger(statusObj.errorMessage, {\n level: 'error',\n });\n }\n }\n\n // Handle delete or keep options\n const deleteOption = options?.deleteLocaleDictionary;\n const keepOption = options?.keepLocaleDictionary;\n\n if (deleteOption && keepOption) {\n throw new Error(\n 'Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.'\n );\n }\n\n if (deleteOption) {\n // Delete only the successfully pushed dictionaries\n await deleteLocalDictionaries(successfullyPushedDictionaries, options);\n } else if (keepOption) {\n // Do nothing, keep the local dictionaries\n } else {\n // Ask the user\n const remoteDictionaries = successfullyPushedDictionaries.filter(\n (dictionary) => dictionary.location === 'remote'\n );\n const remoteDictionariesKeys = remoteDictionaries.map(\n (dictionary) => dictionary.key\n );\n\n if (remoteDictionaries.length > 0) {\n const { confirm, isCancel } = await loadPrompts();\n\n const shouldDelete = await confirm({\n message: `Do you want to delete the local dictionaries that were successfully pushed? ${colorize('(Dictionaries:', ANSIColors.GREY, ANSIColors.RESET)} ${colorizeKey(remoteDictionariesKeys)}${colorize(')', ANSIColors.GREY, ANSIColors.RESET)}`,\n initialValue: false,\n });\n\n if (isCancel(shouldDelete)) {\n return;\n }\n\n if (shouldDelete) {\n await deleteLocalDictionaries(remoteDictionaries, options);\n }\n }\n }\n } catch (error) {\n appLogger(error, {\n level: 'error',\n });\n }\n};\n\nconst deleteLocalDictionaries = async (\n dictionariesToDelete: Dictionary[],\n options?: PushOptions\n): Promise<void> => {\n const config = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(config);\n\n // Use a Set to collect all unique file paths\n const filePathsSet: Set<string> = new Set();\n\n for (const dictionary of dictionariesToDelete) {\n const { filePath } = dictionary;\n\n if (!filePath) {\n appLogger(\n `Dictionary ${colorizeKey(dictionary.key)} does not have a file path`,\n {\n level: 'error',\n }\n );\n continue;\n }\n\n filePathsSet.add(filePath);\n }\n\n for (const filePath of filePathsSet) {\n try {\n const stats = await fsPromises.lstat(filePath);\n\n if (stats.isFile()) {\n await fsPromises.unlink(filePath);\n appLogger(`Deleted file ${formatPath(filePath)}`, {});\n } else if (stats.isDirectory()) {\n appLogger(`Path is a directory ${formatPath(filePath)}, skipping.`, {});\n } else {\n appLogger(\n `Unknown file type for ${formatPath(filePath)}, skipping.`,\n {}\n );\n }\n } catch (err) {\n appLogger(`Error deleting ${formatPath(filePath)}: ${err}`, {\n level: 'error',\n });\n }\n }\n};\n"],"mappings":"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"}
|
package/dist/cjs/pushConfig.cjs
CHANGED
|
@@ -21,7 +21,7 @@ const pushConfig = async (options) => {
|
|
|
21
21
|
}
|
|
22
22
|
appLogger("Project configuration pushed successfully");
|
|
23
23
|
appLogger((0, _intlayer_config_logger.colorize)("--------------------------------", _intlayer_config_colors.GREY_DARK));
|
|
24
|
-
appLogger((0, _intlayer_config_logger.colorizeObject)(getDictionariesKeysResult.data
|
|
24
|
+
appLogger((0, _intlayer_config_logger.colorizeObject)(getDictionariesKeysResult.data));
|
|
25
25
|
appLogger((0, _intlayer_config_logger.colorize)("--------------------------------", _intlayer_config_colors.GREY_DARK));
|
|
26
26
|
};
|
|
27
27
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pushConfig.cjs","names":["getConfiguration","getAppLogger","checkCMSAuth","getAuthenticatedAPI","selectCmsEnvironment","colorize","CYAN","GREY_DARK","colorizeObject"],"sources":["../../src/pushConfig.ts"],"sourcesContent":["import { CYAN, GREY_DARK } from '@intlayer/config/colors';\nimport {\n colorize,\n colorizeObject,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { logConfigDetails } from '@intlayer/engine/cli';\nimport { checkCMSAuth, getAuthenticatedAPI } from './utils/checkAccess';\nimport { selectCmsEnvironment } from './utils/selectCmsEnvironment';\n\ntype PushOptions = {\n configOptions?: GetConfigurationOptions;\n};\n\nexport const pushConfig = async (options?: PushOptions) => {\n const config = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(config);\n\n const hasCMSAuth = await checkCMSAuth(config, false);\n\n if (!hasCMSAuth) return;\n\n const intlayerAPI = await getAuthenticatedAPI(config);\n\n await selectCmsEnvironment(options?.configOptions?.env, intlayerAPI, config);\n\n // Push the project configuration\n const getDictionariesKeysResult =\n await intlayerAPI.project.pushProjectConfiguration(config);\n\n if (!getDictionariesKeysResult.data) {\n appLogger(\n `Error pushing project configuration. Run ${colorize('npx intlayer login', CYAN)} command to authenticate.`,\n {\n level: 'error',\n }\n );\n throw new Error('Error pushing project configuration');\n }\n\n appLogger('Project configuration pushed successfully');\n\n appLogger(colorize('--------------------------------', GREY_DARK));\n appLogger(colorizeObject(getDictionariesKeysResult.data
|
|
1
|
+
{"version":3,"file":"pushConfig.cjs","names":["getConfiguration","getAppLogger","checkCMSAuth","getAuthenticatedAPI","selectCmsEnvironment","colorize","CYAN","GREY_DARK","colorizeObject"],"sources":["../../src/pushConfig.ts"],"sourcesContent":["import { CYAN, GREY_DARK } from '@intlayer/config/colors';\nimport {\n colorize,\n colorizeObject,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { logConfigDetails } from '@intlayer/engine/cli';\nimport { checkCMSAuth, getAuthenticatedAPI } from './utils/checkAccess';\nimport { selectCmsEnvironment } from './utils/selectCmsEnvironment';\n\ntype PushOptions = {\n configOptions?: GetConfigurationOptions;\n};\n\nexport const pushConfig = async (options?: PushOptions) => {\n const config = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(config);\n\n const hasCMSAuth = await checkCMSAuth(config, false);\n\n if (!hasCMSAuth) return;\n\n const intlayerAPI = await getAuthenticatedAPI(config);\n\n await selectCmsEnvironment(options?.configOptions?.env, intlayerAPI, config);\n\n // Push the project configuration\n const getDictionariesKeysResult =\n await intlayerAPI.project.pushProjectConfiguration(config);\n\n if (!getDictionariesKeysResult.data) {\n appLogger(\n `Error pushing project configuration. Run ${colorize('npx intlayer login', CYAN)} command to authenticate.`,\n {\n level: 'error',\n }\n );\n throw new Error('Error pushing project configuration');\n }\n\n appLogger('Project configuration pushed successfully');\n\n appLogger(colorize('--------------------------------', GREY_DARK));\n appLogger(colorizeObject(getDictionariesKeysResult.data));\n appLogger(colorize('--------------------------------', GREY_DARK));\n};\n"],"mappings":";;;;;;;;;AAkBA,MAAa,aAAa,OAAO,YAA0B;CACzD,MAAM,aAASA,wCAAiB,SAAS,aAAa;CACtD,2CAAiB,SAAS,aAAa;CAEvC,MAAM,gBAAYC,sCAAa,MAAM;CAIrC,IAAI,CAAC,MAFoBC,uCAAa,QAAQ,KAAK,GAElC;CAEjB,MAAM,cAAc,MAAMC,8CAAoB,MAAM;CAEpD,MAAMC,wDAAqB,SAAS,eAAe,KAAK,aAAa,MAAM;CAG3E,MAAM,4BACJ,MAAM,YAAY,QAAQ,yBAAyB,MAAM;CAE3D,IAAI,CAAC,0BAA0B,MAAM;EACnC,UACE,gDAA4CC,kCAAS,sBAAsBC,4BAAI,EAAE,4BACjF,EACE,OAAO,QACT,CACF;EACA,MAAM,IAAI,MAAM,qCAAqC;CACvD;CAEA,UAAU,2CAA2C;CAErD,cAAUD,kCAAS,oCAAoCE,iCAAS,CAAC;CACjE,cAAUC,wCAAe,0BAA0B,IAAI,CAAC;CACxD,cAAUH,kCAAS,oCAAoCE,iCAAS,CAAC;AACnE"}
|
package/dist/cjs/watch.cjs
CHANGED
|
@@ -20,6 +20,11 @@ const watchContentDeclaration = async (options) => {
|
|
|
20
20
|
const config = (0, _intlayer_config_node.getConfiguration)(options?.configOptions);
|
|
21
21
|
(0, _intlayer_engine_cli.logConfigDetails)(options?.configOptions);
|
|
22
22
|
const appLogger = (0, _intlayer_config_logger.getAppLogger)(config);
|
|
23
|
+
const bundlerAlreadyWatching = await (0, _intlayer_engine_utils.claimCliContentWatcher)(config, "intlayer watch");
|
|
24
|
+
if (bundlerAlreadyWatching) (0, _intlayer_engine_utils.reportRedundantContentWatcher)(config, {
|
|
25
|
+
cliLabel: "intlayer watch",
|
|
26
|
+
bundlerLabel: bundlerAlreadyWatching.label
|
|
27
|
+
});
|
|
23
28
|
let parallelProcess;
|
|
24
29
|
let isShuttingDown = false;
|
|
25
30
|
if (options?.with) {
|
package/dist/cjs/watch.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.cjs","names":["getConfiguration","getAppLogger","runParallel","watch"],"sources":["../../src/watch.ts"],"sourcesContent":["import { getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { logConfigDetails } from '@intlayer/engine/cli';\nimport {
|
|
1
|
+
{"version":3,"file":"watch.cjs","names":["getConfiguration","getAppLogger","claimCliContentWatcher","runParallel","watch"],"sources":["../../src/watch.ts"],"sourcesContent":["import { getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { logConfigDetails } from '@intlayer/engine/cli';\nimport {\n claimCliContentWatcher,\n reportRedundantContentWatcher,\n runParallel,\n} from '@intlayer/engine/utils';\nimport { watch } from '@intlayer/engine/watcher';\n\ntype WatchOptions = {\n skipPrepare?: boolean;\n with?: string | string[];\n configOptions?: GetConfigurationOptions;\n};\n\n/**\n * Grace period granted to the `--with` child (e.g. Next.js/Turbopack) to exit\n * after SIGTERM before it is force-killed with SIGKILL. Detached dev servers\n * that ignore SIGTERM would otherwise re-orphan once the watcher exits.\n */\nconst SHUTDOWN_GRACE_MS = 3000;\n\n/**\n * Get locales dictionaries .content.{json|ts|tsx|js|jsx|mjs|cjs} and build the JSON dictionaries in the .intlayer directory.\n * Watch mode available to get the change in the .content.{json|ts|tsx|js|jsx|mjs|cjs}\n */\nexport const watchContentDeclaration = async (options?: WatchOptions) => {\n const config = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(config);\n\n // Claimed *before* the child is spawned so the bundler plugin inside it never\n // races this command for the watcher, and inherits the marker telling it a\n // CLI watcher is already covering the project.\n const bundlerAlreadyWatching = await claimCliContentWatcher(\n config,\n 'intlayer watch'\n );\n\n // A bundler integration started from another terminal already covers this\n // project, so this command has become the redundant half.\n if (bundlerAlreadyWatching) {\n reportRedundantContentWatcher(config, {\n cliLabel: 'intlayer watch',\n bundlerLabel: bundlerAlreadyWatching.label,\n });\n }\n\n // Store references to the child process\n let parallelProcess: ReturnType<typeof runParallel> | undefined;\n\n // Declared before the child is spawned so the failure handler below can tell a\n // genuine crash apart from the SIGKILL we send during shutdown.\n let isShuttingDown = false;\n\n if (options?.with) {\n parallelProcess = runParallel(options.with);\n // Handle the promise to avoid unhandled rejection\n parallelProcess.result.catch(() => {\n // During shutdown the child is expected to reject (we force-kill it); that\n // must not be reported as a crash.\n if (isShuttingDown) return;\n // Parallel process failed or was terminated\n process.exit(1);\n });\n }\n\n // Capture the watcher instance\n const watcher = await watch({\n persistent: true,\n skipPrepare: options?.skipPrepare ?? false,\n });\n\n // Define a Graceful Shutdown function\n const handleShutdown = async () => {\n // Prevent multiple calls\n if (isShuttingDown) return;\n isShuttingDown = true;\n\n appLogger('Stopping Intlayer watcher...');\n\n try {\n // Kill the parallel process (e.g., Next.js) before closing the watcher.\n // The child is spawned detached (its own process group), so we must wait\n // for it to actually exit — otherwise it re-orphans the moment we exit.\n if (parallelProcess) {\n const { kill, result } = parallelProcess;\n\n kill('SIGTERM'); // graceful termination of the whole process group\n\n // Escalate to SIGKILL if the child ignores SIGTERM within the grace\n // period (some dev servers/bundlers do), so it can never be left behind.\n let killTimer: NodeJS.Timeout | undefined;\n const graceDeadline = new Promise<void>((resolveDeadline) => {\n killTimer = setTimeout(() => {\n appLogger(\n 'Parallel process did not exit after SIGTERM, sending SIGKILL...',\n { level: 'warn' }\n );\n kill('SIGKILL');\n resolveDeadline();\n }, SHUTDOWN_GRACE_MS);\n });\n\n // `result` rejects when the child is killed; swallow it here since the\n // outcome is already handled by the shutdown-aware catch above.\n await Promise.race([result.catch(() => {}), graceDeadline]);\n\n if (killTimer) clearTimeout(killTimer);\n }\n\n // Close all file watchers to stop \"esbuild service not running\" errors\n await Promise.all(\n watcher?.map((watcherEl) => watcherEl.unsubscribe()) ?? []\n );\n } catch (error) {\n console.error('Error during shutdown:', error);\n } finally {\n process.exit(0);\n }\n };\n\n // Attach Signal Listeners\n process.on('SIGINT', handleShutdown);\n process.on('SIGTERM', handleShutdown);\n};\n"],"mappings":";;;;;;;;;;;;;AAwBA,MAAM,oBAAoB;;;;;AAM1B,MAAa,0BAA0B,OAAO,YAA2B;CACvE,MAAM,aAASA,wCAAiB,SAAS,aAAa;CACtD,2CAAiB,SAAS,aAAa;CAEvC,MAAM,gBAAYC,sCAAa,MAAM;CAKrC,MAAM,yBAAyB,UAAMC,+CACnC,QACA,gBACF;CAIA,IAAI,wBACF,0DAA8B,QAAQ;EACpC,UAAU;EACV,cAAc,uBAAuB;CACvC,CAAC;CAIH,IAAI;CAIJ,IAAI,iBAAiB;CAErB,IAAI,SAAS,MAAM;EACjB,sBAAkBC,oCAAY,QAAQ,IAAI;EAE1C,gBAAgB,OAAO,YAAY;GAGjC,IAAI,gBAAgB;GAEpB,QAAQ,KAAK,CAAC;EAChB,CAAC;CACH;CAGA,MAAM,UAAU,UAAMC,gCAAM;EAC1B,YAAY;EACZ,aAAa,SAAS,eAAe;CACvC,CAAC;CAGD,MAAM,iBAAiB,YAAY;EAEjC,IAAI,gBAAgB;EACpB,iBAAiB;EAEjB,UAAU,8BAA8B;EAExC,IAAI;GAIF,IAAI,iBAAiB;IACnB,MAAM,EAAE,MAAM,WAAW;IAEzB,KAAK,SAAS;IAId,IAAI;IACJ,MAAM,gBAAgB,IAAI,SAAe,oBAAoB;KAC3D,YAAY,iBAAiB;MAC3B,UACE,mEACA,EAAE,OAAO,OAAO,CAClB;MACA,KAAK,SAAS;MACd,gBAAgB;KAClB,GAAG,iBAAiB;IACtB,CAAC;IAID,MAAM,QAAQ,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC,GAAG,aAAa,CAAC;IAE1D,IAAI,WAAW,aAAa,SAAS;GACvC;GAGA,MAAM,QAAQ,IACZ,SAAS,KAAK,cAAc,UAAU,YAAY,CAAC,KAAK,CAAC,CAC3D;EACF,SAAS,OAAO;GACd,QAAQ,MAAM,0BAA0B,KAAK;EAC/C,UAAU;GACR,QAAQ,KAAK,CAAC;EAChB;CACF;CAGA,QAAQ,GAAG,UAAU,cAAc;CACnC,QAAQ,GAAG,WAAW,cAAc;AACtC"}
|
package/dist/esm/build.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getConfiguration } from "@intlayer/config/node";
|
|
2
2
|
import { logConfigDetails } from "@intlayer/engine/cli";
|
|
3
|
-
import { runParallel } from "@intlayer/engine/utils";
|
|
3
|
+
import { claimCliContentWatcher, reportRedundantContentWatcher, runParallel } from "@intlayer/engine/utils";
|
|
4
4
|
import { buildAndWatchIntlayer } from "@intlayer/engine/watcher";
|
|
5
5
|
|
|
6
6
|
//#region src/build.ts
|
|
@@ -12,6 +12,13 @@ const build = async (options) => {
|
|
|
12
12
|
const config = getConfiguration(options?.configOptions);
|
|
13
13
|
logConfigDetails(options?.configOptions);
|
|
14
14
|
let parallelProcess = null;
|
|
15
|
+
if (options?.watch) {
|
|
16
|
+
const bundlerAlreadyWatching = await claimCliContentWatcher(config, "intlayer build --watch");
|
|
17
|
+
if (bundlerAlreadyWatching) reportRedundantContentWatcher(config, {
|
|
18
|
+
cliLabel: "intlayer build --watch",
|
|
19
|
+
bundlerLabel: bundlerAlreadyWatching.label
|
|
20
|
+
});
|
|
21
|
+
}
|
|
15
22
|
if (options?.with) {
|
|
16
23
|
parallelProcess = runParallel(options.with);
|
|
17
24
|
parallelProcess.result.catch(() => {});
|
package/dist/esm/build.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.mjs","names":[],"sources":["../../src/build.ts"],"sourcesContent":["import {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { logConfigDetails } from '@intlayer/engine/cli';\nimport {
|
|
1
|
+
{"version":3,"file":"build.mjs","names":[],"sources":["../../src/build.ts"],"sourcesContent":["import {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { logConfigDetails } from '@intlayer/engine/cli';\nimport {\n claimCliContentWatcher,\n type ParallelHandle,\n reportRedundantContentWatcher,\n runParallel,\n} from '@intlayer/engine/utils';\nimport { buildAndWatchIntlayer } from '@intlayer/engine/watcher';\n\ntype BuildOptions = {\n watch?: boolean;\n skipPrepare?: boolean;\n with?: string | string[];\n configOptions?: GetConfigurationOptions;\n};\n\n/**\n * Get locales dictionaries .content.{json|ts|tsx|js|jsx|mjs|cjs} and build the JSON dictionaries in the .intlayer directory.\n * Watch mode available to get the change in the .content.{json|ts|tsx|js|jsx|mjs|cjs}\n */\nexport const build = async (options?: BuildOptions) => {\n const config = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n let parallelProcess: ParallelHandle | null = null;\n\n // Only watch mode keeps a watcher alive; a one-off build has nothing to\n // deduplicate. Claimed before the child is spawned so the bundler plugin\n // inside it stands down instead of racing this command.\n if (options?.watch) {\n const bundlerAlreadyWatching = await claimCliContentWatcher(\n config,\n 'intlayer build --watch'\n );\n\n if (bundlerAlreadyWatching) {\n reportRedundantContentWatcher(config, {\n cliLabel: 'intlayer build --watch',\n bundlerLabel: bundlerAlreadyWatching.label,\n });\n }\n }\n\n if (options?.with) {\n parallelProcess = runParallel(options.with);\n // Handle the promise to avoid unhandled rejection\n parallelProcess.result.catch(() => {\n // Parallel process failed or was terminated\n });\n }\n\n await buildAndWatchIntlayer({\n persistent: options?.watch ?? false,\n skipPrepare: options?.skipPrepare ?? false,\n configuration: config,\n });\n\n if (!options?.watch && parallelProcess) {\n parallelProcess.kill();\n }\n};\n"],"mappings":";;;;;;;;;;AAwBA,MAAa,QAAQ,OAAO,YAA2B;CACrD,MAAM,SAAS,iBAAiB,SAAS,aAAa;CACtD,iBAAiB,SAAS,aAAa;CAEvC,IAAI,kBAAyC;CAK7C,IAAI,SAAS,OAAO;EAClB,MAAM,yBAAyB,MAAM,uBACnC,QACA,wBACF;EAEA,IAAI,wBACF,8BAA8B,QAAQ;GACpC,UAAU;GACV,cAAc,uBAAuB;EACvC,CAAC;CAEL;CAEA,IAAI,SAAS,MAAM;EACjB,kBAAkB,YAAY,QAAQ,IAAI;EAE1C,gBAAgB,OAAO,YAAY,CAEnC,CAAC;CACH;CAEA,MAAM,sBAAsB;EAC1B,YAAY,SAAS,SAAS;EAC9B,aAAa,SAAS,eAAe;EACrC,eAAe;CACjB,CAAC;CAED,IAAI,CAAC,SAAS,SAAS,iBACrB,gBAAgB,KAAK;AAEzB"}
|