@intlayer/engine 9.0.0-canary.15 → 9.0.0-canary.16
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/cjs/cli.cjs +1 -0
- package/dist/cjs/init/index.cjs +6 -5
- package/dist/cjs/init/index.cjs.map +1 -1
- package/dist/cjs/init/utils/githubActions.cjs +130 -18
- package/dist/cjs/init/utils/githubActions.cjs.map +1 -1
- package/dist/cjs/init/utils/index.cjs +2 -1
- package/dist/cjs/listProjects.cjs +3 -1
- package/dist/cjs/listProjects.cjs.map +1 -1
- package/dist/cjs/writeConfiguration/generateConfigurationContent.cjs +4 -2
- package/dist/cjs/writeConfiguration/generateConfigurationContent.cjs.map +1 -1
- package/dist/esm/cli.mjs +2 -2
- package/dist/esm/init/index.mjs +7 -6
- package/dist/esm/init/index.mjs.map +1 -1
- package/dist/esm/init/utils/githubActions.mjs +130 -19
- package/dist/esm/init/utils/githubActions.mjs.map +1 -1
- package/dist/esm/init/utils/index.mjs +3 -3
- package/dist/esm/listProjects.mjs +3 -2
- package/dist/esm/listProjects.mjs.map +1 -1
- package/dist/esm/writeConfiguration/generateConfigurationContent.mjs +4 -2
- package/dist/esm/writeConfiguration/generateConfigurationContent.mjs.map +1 -1
- package/dist/types/cli.d.ts +2 -2
- package/dist/types/init/index.d.ts.map +1 -1
- package/dist/types/init/utils/githubActions.d.ts +57 -3
- package/dist/types/init/utils/githubActions.d.ts.map +1 -1
- package/dist/types/init/utils/index.d.ts +2 -2
- package/dist/types/listProjects.d.ts +6 -1
- package/dist/types/listProjects.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -1,14 +1,100 @@
|
|
|
1
|
+
import { getGitRootDir, listProjects } from "../../listProjects.mjs";
|
|
2
|
+
import { detectPackageManager } from "./packageManager.mjs";
|
|
3
|
+
import { join, relative, resolve, sep } from "node:path";
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
|
|
1
6
|
//#region src/init/utils/githubActions.ts
|
|
2
7
|
/**
|
|
8
|
+
* Returns true when the repository root hosts a workspace manifest
|
|
9
|
+
* (a `package.json` `workspaces` field or a `pnpm-workspace.yaml`), meaning a
|
|
10
|
+
* single install at the root covers every package of the monorepo.
|
|
11
|
+
*/
|
|
12
|
+
const hasWorkspaceManifest = (repositoryRootDir) => {
|
|
13
|
+
if (existsSync(join(repositoryRootDir, "pnpm-workspace.yaml"))) return true;
|
|
14
|
+
try {
|
|
15
|
+
const packageJsonPath = join(repositoryRootDir, "package.json");
|
|
16
|
+
if (!existsSync(packageJsonPath)) return false;
|
|
17
|
+
const { workspaces } = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
18
|
+
return Boolean(workspaces);
|
|
19
|
+
} catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Resolves where the CI workflows must be written and how their commands must
|
|
25
|
+
* be generated, based on the repository layout around `rootDir` (the Intlayer
|
|
26
|
+
* project being initialized):
|
|
27
|
+
*
|
|
28
|
+
* - Project at the repository root: workflows are written in place. When the
|
|
29
|
+
* repository is a monorepo (workspace manifest, or several Intlayer projects
|
|
30
|
+
* discovered by `listProjects`), the commands go through `intlayer ci` so
|
|
31
|
+
* every project is covered.
|
|
32
|
+
* - Project nested in a repository whose root has a `package.json`
|
|
33
|
+
* (workspace-managed monorepo): workflows are written at the git root —
|
|
34
|
+
* GitHub ignores `.github/workflows` in subdirectories — dependencies are
|
|
35
|
+
* installed at the root with the root's package manager, and the commands go
|
|
36
|
+
* through `intlayer ci` to iterate every Intlayer project.
|
|
37
|
+
* - Project nested in a repository without a root `package.json`: workflows
|
|
38
|
+
* are written at the git root but run inside the project directory
|
|
39
|
+
* (`working-directory`), keeping the project's own package manager.
|
|
40
|
+
*/
|
|
41
|
+
const resolveGithubWorkflowsContext = async (rootDir, projectPackageManager) => {
|
|
42
|
+
const projectRootDir = resolve(rootDir);
|
|
43
|
+
let repositoryRootDir = projectRootDir;
|
|
44
|
+
try {
|
|
45
|
+
const gitRootDir = await getGitRootDir(projectRootDir);
|
|
46
|
+
if (gitRootDir) repositoryRootDir = resolve(gitRootDir);
|
|
47
|
+
} catch {}
|
|
48
|
+
let repositoryProjectCount = 0;
|
|
49
|
+
try {
|
|
50
|
+
const { projectsPath } = await listProjects({ baseDir: repositoryRootDir });
|
|
51
|
+
repositoryProjectCount = projectsPath.length;
|
|
52
|
+
} catch {
|
|
53
|
+
repositoryProjectCount = 0;
|
|
54
|
+
}
|
|
55
|
+
const isNestedProject = repositoryRootDir !== projectRootDir;
|
|
56
|
+
const isWorkspaceRepository = hasWorkspaceManifest(repositoryRootDir);
|
|
57
|
+
const hasRootPackageJson = existsSync(join(repositoryRootDir, "package.json"));
|
|
58
|
+
if (!isNestedProject) return {
|
|
59
|
+
workflowsRootDir: projectRootDir,
|
|
60
|
+
packageManager: projectPackageManager,
|
|
61
|
+
options: { useCiCommand: isWorkspaceRepository || repositoryProjectCount > 1 }
|
|
62
|
+
};
|
|
63
|
+
if (hasRootPackageJson) return {
|
|
64
|
+
workflowsRootDir: repositoryRootDir,
|
|
65
|
+
packageManager: detectPackageManager(repositoryRootDir),
|
|
66
|
+
options: { useCiCommand: true }
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
workflowsRootDir: repositoryRootDir,
|
|
70
|
+
packageManager: projectPackageManager,
|
|
71
|
+
options: { workingDirectory: relative(repositoryRootDir, projectRootDir).split(sep).join("/") }
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
/** Dependency lock file of each package manager, used for cache invalidation. */
|
|
75
|
+
const LOCK_FILE_BY_PACKAGE_MANAGER = {
|
|
76
|
+
bun: "bun.lock",
|
|
77
|
+
pnpm: "pnpm-lock.yaml",
|
|
78
|
+
yarn: "yarn.lock",
|
|
79
|
+
npm: "package-lock.json"
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
3
82
|
* Returns the package-manager-specific steps and commands used to build the
|
|
4
83
|
* GitHub Actions workflows. Each package manager needs a slightly different
|
|
5
84
|
* setup action and a different way to run the local `intlayer` binary.
|
|
85
|
+
*
|
|
86
|
+
* `workingDirectory` is the repository-relative directory holding the lock
|
|
87
|
+
* file when the project is nested: `actions/setup-node` looks for the lock
|
|
88
|
+
* file at the repository root by default and fails the cache setup otherwise.
|
|
6
89
|
*/
|
|
7
|
-
const getPackageManagerCIConfig = (packageManager) => {
|
|
8
|
-
const setupNodeStep = (cache) =>
|
|
90
|
+
const getPackageManagerCIConfig = (packageManager, workingDirectory) => {
|
|
91
|
+
const setupNodeStep = (cache) => {
|
|
92
|
+
const cacheDependencyPath = cache && workingDirectory ? `\n cache-dependency-path: ${workingDirectory}/${LOCK_FILE_BY_PACKAGE_MANAGER[cache]}` : "";
|
|
93
|
+
return ` - name: 🟢 Setup Node.js
|
|
9
94
|
uses: actions/setup-node@v4
|
|
10
95
|
with:
|
|
11
|
-
node-version: 20${cache ? `\n cache: ${cache}` : ""}`;
|
|
96
|
+
node-version: 20${cache ? `\n cache: ${cache}` : ""}${cacheDependencyPath}`;
|
|
97
|
+
};
|
|
12
98
|
switch (packageManager) {
|
|
13
99
|
case "bun": return {
|
|
14
100
|
setupSteps: ` - name: 🥟 Setup Bun
|
|
@@ -36,6 +122,27 @@ ${setupNodeStep("pnpm")}`,
|
|
|
36
122
|
}
|
|
37
123
|
};
|
|
38
124
|
/**
|
|
125
|
+
* Renders the `defaults.run.working-directory` block for jobs that must run
|
|
126
|
+
* inside a nested project directory. Empty when the commands run at the
|
|
127
|
+
* repository root.
|
|
128
|
+
*/
|
|
129
|
+
const getWorkingDirectoryBlock = (workingDirectory) => workingDirectory ? `
|
|
130
|
+
defaults:
|
|
131
|
+
run:
|
|
132
|
+
working-directory: ${workingDirectory}` : "";
|
|
133
|
+
/**
|
|
134
|
+
* Renders the env comment + optional wiring for per-project credentials in
|
|
135
|
+
* monorepo (`intlayer ci`) mode. The `ci` command matches each entry of the
|
|
136
|
+
* `INTLAYER_PROJECT_CREDENTIALS` JSON map to a discovered project path and
|
|
137
|
+
* injects its access keys before running the command in that project.
|
|
138
|
+
*/
|
|
139
|
+
const getMonorepoCredentialsBlock = (useCiCommand) => useCiCommand ? `
|
|
140
|
+
#
|
|
141
|
+
# Monorepo — per-project CMS credentials, as a JSON map of project path
|
|
142
|
+
# (relative to the repository root) to access keys, e.g.
|
|
143
|
+
# {"apps/web":{"clientId":"...","clientSecret":"..."}}:
|
|
144
|
+
# INTLAYER_PROJECT_CREDENTIALS: \${{ secrets.INTLAYER_PROJECT_CREDENTIALS }}` : "";
|
|
145
|
+
/**
|
|
39
146
|
* Builds the `intlayer fill` workflow. Runs on pull requests, regenerates the
|
|
40
147
|
* missing translations for the changed dictionaries (`--git-diff`) using AI,
|
|
41
148
|
* then commits the result back to the PR branch.
|
|
@@ -44,8 +151,9 @@ ${setupNodeStep("pnpm")}`,
|
|
|
44
151
|
* - a provider API key (`AI_API_KEY` secret), forwarded via CLI flags, or
|
|
45
152
|
* - Intlayer CMS access keys (`INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET`).
|
|
46
153
|
*/
|
|
47
|
-
const generateFillWorkflow = (packageManager) => {
|
|
48
|
-
const { setupSteps, installCommand, execCommand } = getPackageManagerCIConfig(packageManager);
|
|
154
|
+
const generateFillWorkflow = (packageManager, options) => {
|
|
155
|
+
const { setupSteps, installCommand, execCommand } = getPackageManagerCIConfig(packageManager, options.workingDirectory);
|
|
156
|
+
const intlayerCommand = options.useCiCommand ? `${execCommand} ci` : execCommand;
|
|
49
157
|
return `name: Intlayer Fill
|
|
50
158
|
# Auto-fill missing translations on every pull request.
|
|
51
159
|
on:
|
|
@@ -63,7 +171,7 @@ concurrency:
|
|
|
63
171
|
|
|
64
172
|
jobs:
|
|
65
173
|
fill:
|
|
66
|
-
runs-on: ubuntu-latest
|
|
174
|
+
runs-on: ubuntu-latest${getWorkingDirectoryBlock(options.workingDirectory)}
|
|
67
175
|
env:
|
|
68
176
|
# AI access is required to generate translations.
|
|
69
177
|
# Add the secret in: Settings → Secrets and variables → Actions.
|
|
@@ -76,7 +184,7 @@ jobs:
|
|
|
76
184
|
# Option 2 — Use Intlayer CMS access keys instead of your own AI key.
|
|
77
185
|
# Wire them in your intlayer.config and uncomment the lines below:
|
|
78
186
|
# INTLAYER_CLIENT_ID: \${{ secrets.INTLAYER_CLIENT_ID }}
|
|
79
|
-
# INTLAYER_CLIENT_SECRET: \${{ secrets.INTLAYER_CLIENT_SECRET }}
|
|
187
|
+
# INTLAYER_CLIENT_SECRET: \${{ secrets.INTLAYER_CLIENT_SECRET }}${getMonorepoCredentialsBlock(options.useCiCommand)}
|
|
80
188
|
steps:
|
|
81
189
|
- name: ⬇️ Checkout repository
|
|
82
190
|
uses: actions/checkout@v4
|
|
@@ -87,12 +195,12 @@ ${setupSteps}
|
|
|
87
195
|
- name: 📦 Install dependencies
|
|
88
196
|
run: ${installCommand}
|
|
89
197
|
- name: ⚙️ Build dictionaries
|
|
90
|
-
run: ${
|
|
198
|
+
run: ${intlayerCommand} build
|
|
91
199
|
- name: 🤖 Fill missing translations
|
|
92
200
|
# Skip when no AI credentials are configured, so the workflow stays green
|
|
93
201
|
# until an \`AI_API_KEY\` (or Intlayer CMS access keys) secret is added.
|
|
94
202
|
if: \${{ env.AI_API_KEY != '' || env.INTLAYER_CLIENT_ID != '' }}
|
|
95
|
-
run: ${
|
|
203
|
+
run: ${intlayerCommand} fill --git-diff --mode complete --provider $AI_PROVIDER --model $AI_MODEL --api-key $AI_API_KEY
|
|
96
204
|
- name: 📤 Commit and push changes
|
|
97
205
|
run: |
|
|
98
206
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
|
@@ -110,8 +218,9 @@ ${setupSteps}
|
|
|
110
218
|
* Builds the `intlayer test` workflow. Runs on pull requests and fails the
|
|
111
219
|
* check when required locales are missing translations. No AI access needed.
|
|
112
220
|
*/
|
|
113
|
-
const generateTestWorkflow = (packageManager) => {
|
|
114
|
-
const { setupSteps, installCommand, execCommand } = getPackageManagerCIConfig(packageManager);
|
|
221
|
+
const generateTestWorkflow = (packageManager, options) => {
|
|
222
|
+
const { setupSteps, installCommand, execCommand } = getPackageManagerCIConfig(packageManager, options.workingDirectory);
|
|
223
|
+
const intlayerCommand = options.useCiCommand ? `${execCommand} ci` : execCommand;
|
|
115
224
|
return `name: Intlayer Test
|
|
116
225
|
# Fail the pull request when required locales are missing translations.
|
|
117
226
|
on:
|
|
@@ -125,7 +234,7 @@ concurrency:
|
|
|
125
234
|
|
|
126
235
|
jobs:
|
|
127
236
|
test:
|
|
128
|
-
runs-on: ubuntu-latest
|
|
237
|
+
runs-on: ubuntu-latest${getWorkingDirectoryBlock(options.workingDirectory)}
|
|
129
238
|
steps:
|
|
130
239
|
- name: ⬇️ Checkout repository
|
|
131
240
|
uses: actions/checkout@v4
|
|
@@ -133,9 +242,9 @@ ${setupSteps}
|
|
|
133
242
|
- name: 📦 Install dependencies
|
|
134
243
|
run: ${installCommand}
|
|
135
244
|
- name: ⚙️ Build dictionaries
|
|
136
|
-
run: ${
|
|
245
|
+
run: ${intlayerCommand} build
|
|
137
246
|
- name: 🧪 Test for missing translations
|
|
138
|
-
run: ${
|
|
247
|
+
run: ${intlayerCommand} test
|
|
139
248
|
`;
|
|
140
249
|
};
|
|
141
250
|
/** Workflow file path constants, relative to the project root. */
|
|
@@ -143,16 +252,18 @@ const GITHUB_FILL_WORKFLOW_PATH = ".github/workflows/intlayer-fill.yml";
|
|
|
143
252
|
const GITHUB_TEST_WORKFLOW_PATH = ".github/workflows/intlayer-test.yml";
|
|
144
253
|
/**
|
|
145
254
|
* Returns the two Intlayer GitHub Actions workflows (`fill` and `test`),
|
|
146
|
-
* generated with commands matching the detected package manager
|
|
255
|
+
* generated with commands matching the detected package manager and the
|
|
256
|
+
* repository layout (see {@link GithubWorkflowsOptions} for the monorepo and
|
|
257
|
+
* nested-project variants).
|
|
147
258
|
*/
|
|
148
|
-
const getGithubWorkflows = (packageManager) => [{
|
|
259
|
+
const getGithubWorkflows = (packageManager, options = {}) => [{
|
|
149
260
|
filePath: GITHUB_FILL_WORKFLOW_PATH,
|
|
150
|
-
content: generateFillWorkflow(packageManager)
|
|
261
|
+
content: generateFillWorkflow(packageManager, options)
|
|
151
262
|
}, {
|
|
152
263
|
filePath: GITHUB_TEST_WORKFLOW_PATH,
|
|
153
|
-
content: generateTestWorkflow(packageManager)
|
|
264
|
+
content: generateTestWorkflow(packageManager, options)
|
|
154
265
|
}];
|
|
155
266
|
|
|
156
267
|
//#endregion
|
|
157
|
-
export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, getGithubWorkflows };
|
|
268
|
+
export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, getGithubWorkflows, resolveGithubWorkflowsContext };
|
|
158
269
|
//# sourceMappingURL=githubActions.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubActions.mjs","names":[],"sources":["../../../../src/init/utils/githubActions.ts"],"sourcesContent":["import type { PackageManager } from './packageManager';\n\n/** A GitHub Actions workflow file to be written to the project. */\nexport type GithubWorkflowFile = {\n /** Path relative to the project root, e.g. `.github/workflows/intlayer-fill.yml`. */\n filePath: string;\n /** Full YAML content of the workflow file. */\n content: string;\n};\n\n/**\n * Package-manager-specific snippets used to assemble the CI workflows.\n * - `setupSteps`: YAML steps (already indented for the `steps:` list) that\n * install the package manager and Node.js, including dependency caching.\n * - `installCommand`: command that installs the project dependencies.\n * - `execCommand`: prefix used to run the locally installed `intlayer` binary.\n */\ntype PackageManagerCIConfig = {\n setupSteps: string;\n installCommand: string;\n execCommand: string;\n};\n\n/**\n * Returns the package-manager-specific steps and commands used to build the\n * GitHub Actions workflows. Each package manager needs a slightly different\n * setup action and a different way to run the local `intlayer` binary.\n */\nconst getPackageManagerCIConfig = (\n packageManager: PackageManager\n): PackageManagerCIConfig => {\n const setupNodeStep = (\n cache: PackageManager | undefined\n ): string => ` - name: 🟢 Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: 20${cache ? `\\n cache: ${cache}` : ''}`;\n\n switch (packageManager) {\n case 'bun':\n return {\n setupSteps: ` - name: 🥟 Setup Bun\n uses: oven-sh/setup-bun@v2`,\n installCommand: 'bun install --frozen-lockfile',\n execCommand: 'bunx intlayer',\n };\n case 'pnpm':\n return {\n setupSteps: ` - name: 📦 Setup pnpm\n uses: pnpm/action-setup@v4\n${setupNodeStep('pnpm')}`,\n installCommand: 'pnpm install --frozen-lockfile',\n execCommand: 'pnpm exec intlayer',\n };\n case 'yarn':\n return {\n setupSteps: setupNodeStep('yarn'),\n installCommand: 'yarn install --frozen-lockfile',\n execCommand: 'yarn intlayer',\n };\n case 'npm':\n return {\n setupSteps: setupNodeStep('npm'),\n installCommand: 'npm ci',\n execCommand: 'npx intlayer',\n };\n }\n};\n\n/**\n * Builds the `intlayer fill` workflow. Runs on pull requests, regenerates the\n * missing translations for the changed dictionaries (`--git-diff`) using AI,\n * then commits the result back to the PR branch.\n *\n * AI access is required for `fill`. The workflow exposes both options:\n * - a provider API key (`AI_API_KEY` secret), forwarded via CLI flags, or\n * - Intlayer CMS access keys (`INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET`).\n */\nconst generateFillWorkflow = (packageManager: PackageManager): string => {\n const { setupSteps, installCommand, execCommand } =\n getPackageManagerCIConfig(packageManager);\n\n return `name: Intlayer Fill\n# Auto-fill missing translations on every pull request.\non:\n pull_request:\n branches:\n - main\n\npermissions:\n contents: write\n pull-requests: write\n\nconcurrency:\n group: intlayer-fill-\\${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n fill:\n runs-on: ubuntu-latest\n env:\n # AI access is required to generate translations.\n # Add the secret in: Settings → Secrets and variables → Actions.\n #\n # Option 1 — Use your own AI provider key (forwarded below via CLI flags):\n AI_PROVIDER: openai\n AI_MODEL: gpt-5-mini\n AI_API_KEY: \\${{ secrets.AI_API_KEY }}\n #\n # Option 2 — Use Intlayer CMS access keys instead of your own AI key.\n # Wire them in your intlayer.config and uncomment the lines below:\n # INTLAYER_CLIENT_ID: \\${{ secrets.INTLAYER_CLIENT_ID }}\n # INTLAYER_CLIENT_SECRET: \\${{ secrets.INTLAYER_CLIENT_SECRET }}\n steps:\n - name: ⬇️ Checkout repository\n uses: actions/checkout@v4\n with:\n persist-credentials: true # Keep credentials to push back to the PR\n fetch-depth: 0 # Full history so --git-diff can compare refs\n${setupSteps}\n - name: 📦 Install dependencies\n run: ${installCommand}\n - name: ⚙️ Build dictionaries\n run: ${execCommand} build\n - name: 🤖 Fill missing translations\n # Skip when no AI credentials are configured, so the workflow stays green\n # until an \\`AI_API_KEY\\` (or Intlayer CMS access keys) secret is added.\n if: \\${{ env.AI_API_KEY != '' || env.INTLAYER_CLIENT_ID != '' }}\n run: ${execCommand} fill --git-diff --mode complete --provider $AI_PROVIDER --model $AI_MODEL --api-key $AI_API_KEY\n - name: 📤 Commit and push changes\n run: |\n git config --local user.email \"github-actions[bot]@users.noreply.github.com\"\n git config --local user.name \"github-actions[bot]\"\n if [ -n \"$(git status --porcelain)\" ]; then\n git add .\n git commit -m \"chore(intlayer): fill missing translations [skip ci]\"\n git push origin HEAD:\\${{ github.head_ref }}\n else\n echo \"No missing translations to fill.\"\n fi\n`;\n};\n\n/**\n * Builds the `intlayer test` workflow. Runs on pull requests and fails the\n * check when required locales are missing translations. No AI access needed.\n */\nconst generateTestWorkflow = (packageManager: PackageManager): string => {\n const { setupSteps, installCommand, execCommand } =\n getPackageManagerCIConfig(packageManager);\n\n return `name: Intlayer Test\n# Fail the pull request when required locales are missing translations.\non:\n pull_request:\n branches:\n - main\n\nconcurrency:\n group: intlayer-test-\\${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - name: ⬇️ Checkout repository\n uses: actions/checkout@v4\n${setupSteps}\n - name: 📦 Install dependencies\n run: ${installCommand}\n - name: ⚙️ Build dictionaries\n run: ${execCommand} build\n - name: 🧪 Test for missing translations\n run: ${execCommand} test\n`;\n};\n\n/** Workflow file path constants, relative to the project root. */\nexport const GITHUB_FILL_WORKFLOW_PATH = '.github/workflows/intlayer-fill.yml';\nexport const GITHUB_TEST_WORKFLOW_PATH = '.github/workflows/intlayer-test.yml';\n\n/**\n * Returns the two Intlayer GitHub Actions workflows (`fill` and `test`),\n * generated with commands matching the detected package manager.\n */\nexport const getGithubWorkflows = (\n packageManager: PackageManager\n): GithubWorkflowFile[] => [\n {\n filePath: GITHUB_FILL_WORKFLOW_PATH,\n content: generateFillWorkflow(packageManager),\n },\n {\n filePath: GITHUB_TEST_WORKFLOW_PATH,\n content: generateTestWorkflow(packageManager),\n },\n];\n"],"mappings":";;;;;;AA4BA,MAAM,6BACJ,mBAC2B;CAC3B,MAAM,iBACJ,UACW;;;4BAGa,QAAQ,sBAAsB,UAAU;AAElE,SAAQ,gBAAR;EACE,KAAK,MACH,QAAO;GACL,YAAY;;GAEZ,gBAAgB;GAChB,aAAa;GACd;EACH,KAAK,OACH,QAAO;GACL,YAAY;;EAElB,cAAc,OAAO;GACf,gBAAgB;GAChB,aAAa;GACd;EACH,KAAK,OACH,QAAO;GACL,YAAY,cAAc,OAAO;GACjC,gBAAgB;GAChB,aAAa;GACd;EACH,KAAK,MACH,QAAO;GACL,YAAY,cAAc,MAAM;GAChC,gBAAgB;GAChB,aAAa;GACd;;;;;;;;;;;;AAaP,MAAM,wBAAwB,mBAA2C;CACvE,MAAM,EAAE,YAAY,gBAAgB,gBAClC,0BAA0B,eAAe;AAE3C,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCP,WAAW;;eAEE,eAAe;;eAEf,YAAY;;;;;eAKZ,YAAY;;;;;;;;;;;;;;;;;;AAmB3B,MAAM,wBAAwB,mBAA2C;CACvE,MAAM,EAAE,YAAY,gBAAgB,gBAClC,0BAA0B,eAAe;AAE3C,QAAO;;;;;;;;;;;;;;;;;EAiBP,WAAW;;eAEE,eAAe;;eAEf,YAAY;;eAEZ,YAAY;;;;AAK3B,MAAa,4BAA4B;AACzC,MAAa,4BAA4B;;;;;AAMzC,MAAa,sBACX,mBACyB,CACzB;CACE,UAAU;CACV,SAAS,qBAAqB,eAAe;CAC9C,EACD;CACE,UAAU;CACV,SAAS,qBAAqB,eAAe;CAC9C,CACF"}
|
|
1
|
+
{"version":3,"file":"githubActions.mjs","names":[],"sources":["../../../../src/init/utils/githubActions.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { join, relative, resolve, sep } from 'node:path';\nimport { getGitRootDir, listProjects } from '../../listProjects';\nimport { detectPackageManager, type PackageManager } from './packageManager';\n\n/** A GitHub Actions workflow file to be written to the project. */\nexport type GithubWorkflowFile = {\n /** Path relative to the project root, e.g. `.github/workflows/intlayer-fill.yml`. */\n filePath: string;\n /** Full YAML content of the workflow file. */\n content: string;\n};\n\n/** Options controlling how the CI workflows are generated. */\nexport type GithubWorkflowsOptions = {\n /**\n * Route the intlayer commands through `intlayer ci` instead of calling them\n * directly. The `ci` command discovers every Intlayer project of the\n * repository (via `listProjects`) and runs the given command inside each of\n * them, injecting per-project credentials from the\n * `INTLAYER_PROJECT_CREDENTIALS` secret when provided. Required for\n * monorepos where a single workflow must cover several projects.\n */\n useCiCommand?: boolean;\n /**\n * Repository-relative directory (posix separators) the workflow commands run\n * in. Set when the Intlayer project lives in a subdirectory of the\n * repository and the repository root has no workspace manifest to install\n * dependencies from. Undefined = repository root.\n */\n workingDirectory?: string;\n};\n\n/**\n * Resolved placement and generation parameters for the CI workflows.\n * See {@link resolveGithubWorkflowsContext}.\n */\nexport type GithubWorkflowsContext = {\n /**\n * Directory the workflow files must be written to. GitHub only triggers\n * workflows stored in `.github/workflows` at the repository root, so this is\n * the git root whenever the project lives inside a git repository.\n */\n workflowsRootDir: string;\n /** Package manager whose commands are baked into the workflows. */\n packageManager: PackageManager;\n /** Generation options forwarded to {@link getGithubWorkflows}. */\n options: GithubWorkflowsOptions;\n};\n\n/**\n * Returns true when the repository root hosts a workspace manifest\n * (a `package.json` `workspaces` field or a `pnpm-workspace.yaml`), meaning a\n * single install at the root covers every package of the monorepo.\n */\nconst hasWorkspaceManifest = (repositoryRootDir: string): boolean => {\n if (existsSync(join(repositoryRootDir, 'pnpm-workspace.yaml'))) {\n return true;\n }\n\n try {\n const packageJsonPath = join(repositoryRootDir, 'package.json');\n if (!existsSync(packageJsonPath)) return false;\n const { workspaces } = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return Boolean(workspaces);\n } catch {\n return false;\n }\n};\n\n/**\n * Resolves where the CI workflows must be written and how their commands must\n * be generated, based on the repository layout around `rootDir` (the Intlayer\n * project being initialized):\n *\n * - Project at the repository root: workflows are written in place. When the\n * repository is a monorepo (workspace manifest, or several Intlayer projects\n * discovered by `listProjects`), the commands go through `intlayer ci` so\n * every project is covered.\n * - Project nested in a repository whose root has a `package.json`\n * (workspace-managed monorepo): workflows are written at the git root —\n * GitHub ignores `.github/workflows` in subdirectories — dependencies are\n * installed at the root with the root's package manager, and the commands go\n * through `intlayer ci` to iterate every Intlayer project.\n * - Project nested in a repository without a root `package.json`: workflows\n * are written at the git root but run inside the project directory\n * (`working-directory`), keeping the project's own package manager.\n */\nexport const resolveGithubWorkflowsContext = async (\n rootDir: string,\n projectPackageManager: PackageManager\n): Promise<GithubWorkflowsContext> => {\n const projectRootDir = resolve(rootDir);\n\n let repositoryRootDir = projectRootDir;\n try {\n const gitRootDir = await getGitRootDir(projectRootDir);\n if (gitRootDir) repositoryRootDir = resolve(gitRootDir);\n } catch {\n // Not a git repository — keep the project root as the workflow root.\n }\n\n // Discover every Intlayer project of the repository. `listProjects` scans\n // for configuration files, so a fresh project whose config is created later\n // in the init flow may not be counted yet — the workspace manifest check\n // below still catches that monorepo case.\n let repositoryProjectCount = 0;\n try {\n const { projectsPath } = await listProjects({\n baseDir: repositoryRootDir,\n });\n repositoryProjectCount = projectsPath.length;\n } catch {\n repositoryProjectCount = 0;\n }\n\n const isNestedProject = repositoryRootDir !== projectRootDir;\n const isWorkspaceRepository = hasWorkspaceManifest(repositoryRootDir);\n const hasRootPackageJson = existsSync(\n join(repositoryRootDir, 'package.json')\n );\n\n if (!isNestedProject) {\n return {\n workflowsRootDir: projectRootDir,\n packageManager: projectPackageManager,\n options: {\n useCiCommand: isWorkspaceRepository || repositoryProjectCount > 1,\n },\n };\n }\n\n if (hasRootPackageJson) {\n return {\n workflowsRootDir: repositoryRootDir,\n packageManager: detectPackageManager(repositoryRootDir),\n options: { useCiCommand: true },\n };\n }\n\n // Nested project without a root manifest: install and run everything inside\n // the project directory itself.\n return {\n workflowsRootDir: repositoryRootDir,\n packageManager: projectPackageManager,\n options: {\n workingDirectory: relative(repositoryRootDir, projectRootDir)\n .split(sep)\n .join('/'),\n },\n };\n};\n\n/**\n * Package-manager-specific snippets used to assemble the CI workflows.\n * - `setupSteps`: YAML steps (already indented for the `steps:` list) that\n * install the package manager and Node.js, including dependency caching.\n * - `installCommand`: command that installs the project dependencies.\n * - `execCommand`: prefix used to run the locally installed `intlayer` binary.\n */\ntype PackageManagerCIConfig = {\n setupSteps: string;\n installCommand: string;\n execCommand: string;\n};\n\n/** Dependency lock file of each package manager, used for cache invalidation. */\nconst LOCK_FILE_BY_PACKAGE_MANAGER: Record<PackageManager, string> = {\n bun: 'bun.lock',\n pnpm: 'pnpm-lock.yaml',\n yarn: 'yarn.lock',\n npm: 'package-lock.json',\n};\n\n/**\n * Returns the package-manager-specific steps and commands used to build the\n * GitHub Actions workflows. Each package manager needs a slightly different\n * setup action and a different way to run the local `intlayer` binary.\n *\n * `workingDirectory` is the repository-relative directory holding the lock\n * file when the project is nested: `actions/setup-node` looks for the lock\n * file at the repository root by default and fails the cache setup otherwise.\n */\nconst getPackageManagerCIConfig = (\n packageManager: PackageManager,\n workingDirectory?: string\n): PackageManagerCIConfig => {\n const setupNodeStep = (cache: PackageManager | undefined): string => {\n const cacheDependencyPath =\n cache && workingDirectory\n ? `\\n cache-dependency-path: ${workingDirectory}/${LOCK_FILE_BY_PACKAGE_MANAGER[cache]}`\n : '';\n\n return ` - name: 🟢 Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: 20${cache ? `\\n cache: ${cache}` : ''}${cacheDependencyPath}`;\n };\n\n switch (packageManager) {\n case 'bun':\n return {\n setupSteps: ` - name: 🥟 Setup Bun\n uses: oven-sh/setup-bun@v2`,\n installCommand: 'bun install --frozen-lockfile',\n execCommand: 'bunx intlayer',\n };\n case 'pnpm':\n return {\n setupSteps: ` - name: 📦 Setup pnpm\n uses: pnpm/action-setup@v4\n${setupNodeStep('pnpm')}`,\n installCommand: 'pnpm install --frozen-lockfile',\n execCommand: 'pnpm exec intlayer',\n };\n case 'yarn':\n return {\n setupSteps: setupNodeStep('yarn'),\n installCommand: 'yarn install --frozen-lockfile',\n execCommand: 'yarn intlayer',\n };\n case 'npm':\n return {\n setupSteps: setupNodeStep('npm'),\n installCommand: 'npm ci',\n execCommand: 'npx intlayer',\n };\n }\n};\n\n/**\n * Renders the `defaults.run.working-directory` block for jobs that must run\n * inside a nested project directory. Empty when the commands run at the\n * repository root.\n */\nconst getWorkingDirectoryBlock = (workingDirectory?: string): string =>\n workingDirectory\n ? `\n defaults:\n run:\n working-directory: ${workingDirectory}`\n : '';\n\n/**\n * Renders the env comment + optional wiring for per-project credentials in\n * monorepo (`intlayer ci`) mode. The `ci` command matches each entry of the\n * `INTLAYER_PROJECT_CREDENTIALS` JSON map to a discovered project path and\n * injects its access keys before running the command in that project.\n */\nconst getMonorepoCredentialsBlock = (useCiCommand?: boolean): string =>\n useCiCommand\n ? `\n #\n # Monorepo — per-project CMS credentials, as a JSON map of project path\n # (relative to the repository root) to access keys, e.g.\n # {\"apps/web\":{\"clientId\":\"...\",\"clientSecret\":\"...\"}}:\n # INTLAYER_PROJECT_CREDENTIALS: \\${{ secrets.INTLAYER_PROJECT_CREDENTIALS }}`\n : '';\n\n/**\n * Builds the `intlayer fill` workflow. Runs on pull requests, regenerates the\n * missing translations for the changed dictionaries (`--git-diff`) using AI,\n * then commits the result back to the PR branch.\n *\n * AI access is required for `fill`. The workflow exposes both options:\n * - a provider API key (`AI_API_KEY` secret), forwarded via CLI flags, or\n * - Intlayer CMS access keys (`INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET`).\n */\nconst generateFillWorkflow = (\n packageManager: PackageManager,\n options: GithubWorkflowsOptions\n): string => {\n const { setupSteps, installCommand, execCommand } = getPackageManagerCIConfig(\n packageManager,\n options.workingDirectory\n );\n\n // In monorepo mode `intlayer ci <command>` discovers every Intlayer project\n // of the repository and runs the command inside each of them.\n const intlayerCommand = options.useCiCommand\n ? `${execCommand} ci`\n : execCommand;\n\n return `name: Intlayer Fill\n# Auto-fill missing translations on every pull request.\non:\n pull_request:\n branches:\n - main\n\npermissions:\n contents: write\n pull-requests: write\n\nconcurrency:\n group: intlayer-fill-\\${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n fill:\n runs-on: ubuntu-latest${getWorkingDirectoryBlock(options.workingDirectory)}\n env:\n # AI access is required to generate translations.\n # Add the secret in: Settings → Secrets and variables → Actions.\n #\n # Option 1 — Use your own AI provider key (forwarded below via CLI flags):\n AI_PROVIDER: openai\n AI_MODEL: gpt-5-mini\n AI_API_KEY: \\${{ secrets.AI_API_KEY }}\n #\n # Option 2 — Use Intlayer CMS access keys instead of your own AI key.\n # Wire them in your intlayer.config and uncomment the lines below:\n # INTLAYER_CLIENT_ID: \\${{ secrets.INTLAYER_CLIENT_ID }}\n # INTLAYER_CLIENT_SECRET: \\${{ secrets.INTLAYER_CLIENT_SECRET }}${getMonorepoCredentialsBlock(options.useCiCommand)}\n steps:\n - name: ⬇️ Checkout repository\n uses: actions/checkout@v4\n with:\n persist-credentials: true # Keep credentials to push back to the PR\n fetch-depth: 0 # Full history so --git-diff can compare refs\n${setupSteps}\n - name: 📦 Install dependencies\n run: ${installCommand}\n - name: ⚙️ Build dictionaries\n run: ${intlayerCommand} build\n - name: 🤖 Fill missing translations\n # Skip when no AI credentials are configured, so the workflow stays green\n # until an \\`AI_API_KEY\\` (or Intlayer CMS access keys) secret is added.\n if: \\${{ env.AI_API_KEY != '' || env.INTLAYER_CLIENT_ID != '' }}\n run: ${intlayerCommand} fill --git-diff --mode complete --provider $AI_PROVIDER --model $AI_MODEL --api-key $AI_API_KEY\n - name: 📤 Commit and push changes\n run: |\n git config --local user.email \"github-actions[bot]@users.noreply.github.com\"\n git config --local user.name \"github-actions[bot]\"\n if [ -n \"$(git status --porcelain)\" ]; then\n git add .\n git commit -m \"chore(intlayer): fill missing translations [skip ci]\"\n git push origin HEAD:\\${{ github.head_ref }}\n else\n echo \"No missing translations to fill.\"\n fi\n`;\n};\n\n/**\n * Builds the `intlayer test` workflow. Runs on pull requests and fails the\n * check when required locales are missing translations. No AI access needed.\n */\nconst generateTestWorkflow = (\n packageManager: PackageManager,\n options: GithubWorkflowsOptions\n): string => {\n const { setupSteps, installCommand, execCommand } = getPackageManagerCIConfig(\n packageManager,\n options.workingDirectory\n );\n\n // In monorepo mode `intlayer ci <command>` discovers every Intlayer project\n // of the repository and runs the command inside each of them.\n const intlayerCommand = options.useCiCommand\n ? `${execCommand} ci`\n : execCommand;\n\n return `name: Intlayer Test\n# Fail the pull request when required locales are missing translations.\non:\n pull_request:\n branches:\n - main\n\nconcurrency:\n group: intlayer-test-\\${{ github.ref }}\n cancel-in-progress: true\n\njobs:\n test:\n runs-on: ubuntu-latest${getWorkingDirectoryBlock(options.workingDirectory)}\n steps:\n - name: ⬇️ Checkout repository\n uses: actions/checkout@v4\n${setupSteps}\n - name: 📦 Install dependencies\n run: ${installCommand}\n - name: ⚙️ Build dictionaries\n run: ${intlayerCommand} build\n - name: 🧪 Test for missing translations\n run: ${intlayerCommand} test\n`;\n};\n\n/** Workflow file path constants, relative to the project root. */\nexport const GITHUB_FILL_WORKFLOW_PATH = '.github/workflows/intlayer-fill.yml';\nexport const GITHUB_TEST_WORKFLOW_PATH = '.github/workflows/intlayer-test.yml';\n\n/**\n * Returns the two Intlayer GitHub Actions workflows (`fill` and `test`),\n * generated with commands matching the detected package manager and the\n * repository layout (see {@link GithubWorkflowsOptions} for the monorepo and\n * nested-project variants).\n */\nexport const getGithubWorkflows = (\n packageManager: PackageManager,\n options: GithubWorkflowsOptions = {}\n): GithubWorkflowFile[] => [\n {\n filePath: GITHUB_FILL_WORKFLOW_PATH,\n content: generateFillWorkflow(packageManager, options),\n },\n {\n filePath: GITHUB_TEST_WORKFLOW_PATH,\n content: generateTestWorkflow(packageManager, options),\n },\n];\n"],"mappings":";;;;;;;;;;;AAuDA,MAAM,wBAAwB,sBAAuC;AACnE,KAAI,WAAW,KAAK,mBAAmB,sBAAsB,CAAC,CAC5D,QAAO;AAGT,KAAI;EACF,MAAM,kBAAkB,KAAK,mBAAmB,eAAe;AAC/D,MAAI,CAAC,WAAW,gBAAgB,CAAE,QAAO;EACzC,MAAM,EAAE,eAAe,KAAK,MAAM,aAAa,iBAAiB,QAAQ,CAAC;AACzE,SAAO,QAAQ,WAAW;SACpB;AACN,SAAO;;;;;;;;;;;;;;;;;;;;;AAsBX,MAAa,gCAAgC,OAC3C,SACA,0BACoC;CACpC,MAAM,iBAAiB,QAAQ,QAAQ;CAEvC,IAAI,oBAAoB;AACxB,KAAI;EACF,MAAM,aAAa,MAAM,cAAc,eAAe;AACtD,MAAI,WAAY,qBAAoB,QAAQ,WAAW;SACjD;CAQR,IAAI,yBAAyB;AAC7B,KAAI;EACF,MAAM,EAAE,iBAAiB,MAAM,aAAa,EAC1C,SAAS,mBACV,CAAC;AACF,2BAAyB,aAAa;SAChC;AACN,2BAAyB;;CAG3B,MAAM,kBAAkB,sBAAsB;CAC9C,MAAM,wBAAwB,qBAAqB,kBAAkB;CACrE,MAAM,qBAAqB,WACzB,KAAK,mBAAmB,eAAe,CACxC;AAED,KAAI,CAAC,gBACH,QAAO;EACL,kBAAkB;EAClB,gBAAgB;EAChB,SAAS,EACP,cAAc,yBAAyB,yBAAyB,GACjE;EACF;AAGH,KAAI,mBACF,QAAO;EACL,kBAAkB;EAClB,gBAAgB,qBAAqB,kBAAkB;EACvD,SAAS,EAAE,cAAc,MAAM;EAChC;AAKH,QAAO;EACL,kBAAkB;EAClB,gBAAgB;EAChB,SAAS,EACP,kBAAkB,SAAS,mBAAmB,eAAe,CAC1D,MAAM,IAAI,CACV,KAAK,IAAI,EACb;EACF;;;AAiBH,MAAM,+BAA+D;CACnE,KAAK;CACL,MAAM;CACN,MAAM;CACN,KAAK;CACN;;;;;;;;;;AAWD,MAAM,6BACJ,gBACA,qBAC2B;CAC3B,MAAM,iBAAiB,UAA8C;EACnE,MAAM,sBACJ,SAAS,mBACL,sCAAsC,iBAAiB,GAAG,6BAA6B,WACvF;AAEN,SAAO;;;4BAGiB,QAAQ,sBAAsB,UAAU,KAAK;;AAGvE,SAAQ,gBAAR;EACE,KAAK,MACH,QAAO;GACL,YAAY;;GAEZ,gBAAgB;GAChB,aAAa;GACd;EACH,KAAK,OACH,QAAO;GACL,YAAY;;EAElB,cAAc,OAAO;GACf,gBAAgB;GAChB,aAAa;GACd;EACH,KAAK,OACH,QAAO;GACL,YAAY,cAAc,OAAO;GACjC,gBAAgB;GAChB,aAAa;GACd;EACH,KAAK,MACH,QAAO;GACL,YAAY,cAAc,MAAM;GAChC,gBAAgB;GAChB,aAAa;GACd;;;;;;;;AASP,MAAM,4BAA4B,qBAChC,mBACI;;;6BAGuB,qBACvB;;;;;;;AAQN,MAAM,+BAA+B,iBACnC,eACI;;;;;sFAMA;;;;;;;;;;AAWN,MAAM,wBACJ,gBACA,YACW;CACX,MAAM,EAAE,YAAY,gBAAgB,gBAAgB,0BAClD,gBACA,QAAQ,iBACT;CAID,MAAM,kBAAkB,QAAQ,eAC5B,GAAG,YAAY,OACf;AAEJ,QAAO;;;;;;;;;;;;;;;;;4BAiBmB,yBAAyB,QAAQ,iBAAiB,CAAC;;;;;;;;;;;;;wEAaP,4BAA4B,QAAQ,aAAa,CAAC;;;;;;;EAOxH,WAAW;;eAEE,eAAe;;eAEf,gBAAgB;;;;;eAKhB,gBAAgB;;;;;;;;;;;;;;;;;;AAmB/B,MAAM,wBACJ,gBACA,YACW;CACX,MAAM,EAAE,YAAY,gBAAgB,gBAAgB,0BAClD,gBACA,QAAQ,iBACT;CAID,MAAM,kBAAkB,QAAQ,eAC5B,GAAG,YAAY,OACf;AAEJ,QAAO;;;;;;;;;;;;;4BAamB,yBAAyB,QAAQ,iBAAiB,CAAC;;;;EAI7E,WAAW;;eAEE,eAAe;;eAEf,gBAAgB;;eAEhB,gBAAgB;;;;AAK/B,MAAa,4BAA4B;AACzC,MAAa,4BAA4B;;;;;;;AAQzC,MAAa,sBACX,gBACA,UAAkC,EAAE,KACX,CACzB;CACE,UAAU;CACV,SAAS,qBAAqB,gBAAgB,QAAQ;CACvD,EACD;CACE,UAAU;CACV,SAAS,qBAAqB,gBAAgB,QAAQ;CACvD,CACF"}
|
|
@@ -2,10 +2,10 @@ import { ensureNamedImport, firstInsertIndex, isModuleScopeBinding } from "./ast
|
|
|
2
2
|
import { enableIntlayerEditorConfig, getMetroConfigTemplate, hasIntlayerVitePlugin, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n } from "./configManipulation.mjs";
|
|
3
3
|
import { detectJsonLocalePattern, detectLinguiCatalogPattern, detectNextIntlMessagesPattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot } from "./fileSystem.mjs";
|
|
4
4
|
import { isVersionAtLeast } from "./version.mjs";
|
|
5
|
-
import { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, getGithubWorkflows } from "./githubActions.mjs";
|
|
6
|
-
import { parseJSONWithComments } from "./jsonParser.mjs";
|
|
7
5
|
import { detectMissingIntlayerPackages, detectOutdatedIntlayerPackages, detectPackageManager, getInstalledPackageVersion, installPackages, isIntlayerPackageName, normalizeVersion, upgradePackages } from "./packageManager.mjs";
|
|
6
|
+
import { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, getGithubWorkflows, resolveGithubWorkflowsContext } from "./githubActions.mjs";
|
|
7
|
+
import { parseJSONWithComments } from "./jsonParser.mjs";
|
|
8
8
|
import { NEXT_INTLAYER_BABEL_CONFIG_CONTENT, setupNextCompilerBabelConfig } from "./nextCompilerBabel.mjs";
|
|
9
9
|
import { findTsConfigFiles } from "./tsConfig.mjs";
|
|
10
10
|
|
|
11
|
-
export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, detectJsonLocalePattern, detectLinguiCatalogPattern, detectMissingIntlayerPackages, detectNextIntlMessagesPattern, detectOutdatedIntlayerPackages, detectPackageManager, enableIntlayerEditorConfig, ensureDirectory, ensureNamedImport, exists, findTsConfigFiles, firstInsertIndex, getGithubWorkflows, getInstalledPackageVersion, getMetroConfigTemplate, hasIntlayerVitePlugin, installPackages, isIntlayerPackageName, isModuleScopeBinding, isVersionAtLeast, normalizeVersion, parseJSONWithComments, readFileFromRoot, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, setupNextCompilerBabelConfig, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, upgradePackages, writeFileToRoot };
|
|
11
|
+
export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, detectJsonLocalePattern, detectLinguiCatalogPattern, detectMissingIntlayerPackages, detectNextIntlMessagesPattern, detectOutdatedIntlayerPackages, detectPackageManager, enableIntlayerEditorConfig, ensureDirectory, ensureNamedImport, exists, findTsConfigFiles, firstInsertIndex, getGithubWorkflows, getInstalledPackageVersion, getMetroConfigTemplate, hasIntlayerVitePlugin, installPackages, isIntlayerPackageName, isModuleScopeBinding, isVersionAtLeast, normalizeVersion, parseJSONWithComments, readFileFromRoot, replaceViteConfigPluginImportSource, resolveGithubWorkflowsContext, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, setupNextCompilerBabelConfig, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, upgradePackages, writeFileToRoot };
|
|
@@ -5,7 +5,8 @@ import simpleGit from "simple-git";
|
|
|
5
5
|
|
|
6
6
|
//#region src/listProjects.ts
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Returns the git repository root directory, or `null` when the given
|
|
9
|
+
* directory is not inside a git repository.
|
|
9
10
|
*/
|
|
10
11
|
const getGitRootDir = async (cwd) => {
|
|
11
12
|
try {
|
|
@@ -40,5 +41,5 @@ const listProjects = async (options) => {
|
|
|
40
41
|
};
|
|
41
42
|
|
|
42
43
|
//#endregion
|
|
43
|
-
export { listProjects };
|
|
44
|
+
export { getGitRootDir, listProjects };
|
|
44
45
|
//# sourceMappingURL=listProjects.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listProjects.mjs","names":[],"sources":["../../src/listProjects.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { configurationFilesCandidates } from '@intlayer/config/node';\nimport fg from 'fast-glob';\nimport simpleGit from 'simple-git';\n\nexport type ListProjectsOptions = {\n /**\n * Base directory to search from\n * @default process.cwd()\n */\n baseDir?: string;\n /**\n * If true, search from the git root directory instead of baseDir\n * @default false\n */\n gitRoot?: boolean;\n};\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"listProjects.mjs","names":[],"sources":["../../src/listProjects.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { configurationFilesCandidates } from '@intlayer/config/node';\nimport fg from 'fast-glob';\nimport simpleGit from 'simple-git';\n\nexport type ListProjectsOptions = {\n /**\n * Base directory to search from\n * @default process.cwd()\n */\n baseDir?: string;\n /**\n * If true, search from the git root directory instead of baseDir\n * @default false\n */\n gitRoot?: boolean;\n};\n\n/**\n * Returns the git repository root directory, or `null` when the given\n * directory is not inside a git repository.\n */\nexport const getGitRootDir = async (cwd?: string): Promise<string | null> => {\n try {\n const git = cwd ? simpleGit(cwd) : simpleGit();\n const rootDir = await git.revparse(['--show-toplevel']);\n return rootDir.trim();\n } catch (_error) {\n return null;\n }\n};\n\n/**\n * List all Intlayer projects by searching for configuration files\n *\n * @param options - Options for listing projects\n * @returns Array of absolute paths to project directories containing Intlayer config\n */\nexport const listProjects = async (\n options?: ListProjectsOptions\n): Promise<{ searchDir: string; projectsPath: string[] }> => {\n let searchDir = options?.baseDir ?? process.cwd();\n\n // If gitRoot option is enabled, try to get the git root directory\n if (options?.gitRoot) {\n const gitRootDir = await getGitRootDir(searchDir);\n if (gitRootDir) {\n searchDir = gitRootDir;\n }\n }\n\n // Build glob patterns for all config file candidates\n const configPatterns = configurationFilesCandidates.map(\n (fileName) => `**/${fileName}`\n );\n\n // Search for all config files\n const configFiles = await fg(configPatterns, {\n cwd: searchDir,\n absolute: true,\n ignore: ['**/node_modules/**', '**/.git/**'],\n dot: true, // Include dot files like .intlayerrc\n });\n\n // Extract unique directory paths from config files\n const projectDirs = [...new Set(configFiles.map((file) => dirname(file)))];\n\n // Sort alphabetically for consistent output\n return { searchDir, projectsPath: projectDirs.sort() };\n};\n"],"mappings":";;;;;;;;;;AAsBA,MAAa,gBAAgB,OAAO,QAAyC;AAC3E,KAAI;AAGF,UAAO,OAFK,MAAM,UAAU,IAAI,GAAG,WAAW,EACpB,SAAS,CAAC,kBAAkB,CAAC,EACxC,MAAM;UACd,QAAQ;AACf,SAAO;;;;;;;;;AAUX,MAAa,eAAe,OAC1B,YAC2D;CAC3D,IAAI,YAAY,SAAS,WAAW,QAAQ,KAAK;AAGjD,KAAI,SAAS,SAAS;EACpB,MAAM,aAAa,MAAM,cAAc,UAAU;AACjD,MAAI,WACF,aAAY;;CAUhB,MAAM,cAAc,MAAM,GALH,6BAA6B,KACjD,aAAa,MAAM,WAIqB,EAAE;EAC3C,KAAK;EACL,UAAU;EACV,QAAQ,CAAC,sBAAsB,aAAa;EAC5C,KAAK;EACN,CAAC;CAGF,MAAM,cAAc,CAAC,GAAG,IAAI,IAAI,YAAY,KAAK,SAAS,QAAQ,KAAK,CAAC,CAAC,CAAC;AAG1E,QAAO;EAAE;EAAW,cAAc,YAAY,MAAM;EAAE"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
//#region src/writeConfiguration/generateConfigurationContent.ts
|
|
2
2
|
const generateConfigurationContent = (configuration, format) => {
|
|
3
|
-
const { internationalization, routing, editor, log, system, content, ai, dictionary, build, compiler } = configuration;
|
|
3
|
+
const { internationalization, routing, editor, analytics, log, system, content, ai, dictionary, build, compiler } = configuration;
|
|
4
4
|
let fileContent = "";
|
|
5
5
|
fileContent += `const internationalization = ${JSON.stringify(internationalization, null, 2)};\n`;
|
|
6
6
|
fileContent += `const routing = ${JSON.stringify(routing, null, 2)};\n`;
|
|
7
7
|
fileContent += `const editor = ${JSON.stringify(editor, null, 2)};\n`;
|
|
8
|
+
fileContent += `const analytics = ${JSON.stringify(analytics, null, 2)};\n`;
|
|
8
9
|
fileContent += `const log = ${JSON.stringify(log, null, 2)};\n`;
|
|
9
10
|
fileContent += `const system = ${JSON.stringify(system, null, 2)};\n`;
|
|
10
11
|
fileContent += `const content = ${JSON.stringify(content, null, 2)};\n`;
|
|
@@ -12,11 +13,12 @@ const generateConfigurationContent = (configuration, format) => {
|
|
|
12
13
|
fileContent += `const dictionary = ${JSON.stringify(dictionary, null, 2)};\n`;
|
|
13
14
|
fileContent += `const build = ${JSON.stringify(build, null, 2)};\n`;
|
|
14
15
|
fileContent += `const compiler = ${JSON.stringify(compiler, null, 2)};\n`;
|
|
15
|
-
if (format === "esm") fileContent += `\nexport { internationalization, routing, editor, log, system, content, ai, dictionary, build, compiler };\n`;
|
|
16
|
+
if (format === "esm") fileContent += `\nexport { internationalization, routing, editor, analytics, log, system, content, ai, dictionary, build, compiler };\n`;
|
|
16
17
|
else {
|
|
17
18
|
fileContent += `\nmodule.exports.internationalization = internationalization;\n`;
|
|
18
19
|
fileContent += `module.exports.routing = routing;\n`;
|
|
19
20
|
fileContent += `module.exports.editor = editor;\n`;
|
|
21
|
+
fileContent += `module.exports.analytics = analytics;\n`;
|
|
20
22
|
fileContent += `module.exports.log = log;\n`;
|
|
21
23
|
fileContent += `module.exports.system = system;\n`;
|
|
22
24
|
fileContent += `module.exports.content = content;\n`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateConfigurationContent.mjs","names":[],"sources":["../../../src/writeConfiguration/generateConfigurationContent.ts"],"sourcesContent":["import type { IntlayerConfig } from '@intlayer/types/config';\n\nexport const generateConfigurationContent = (\n configuration: IntlayerConfig,\n format: 'cjs' | 'esm'\n): string => {\n const {\n internationalization,\n routing,\n editor,\n log,\n system,\n content,\n ai,\n dictionary,\n build,\n compiler,\n } = configuration;\n\n let fileContent = '';\n\n fileContent += `const internationalization = ${JSON.stringify(internationalization, null, 2)};\\n`;\n fileContent += `const routing = ${JSON.stringify(routing, null, 2)};\\n`;\n fileContent += `const editor = ${JSON.stringify(editor, null, 2)};\\n`;\n fileContent += `const log = ${JSON.stringify(log, null, 2)};\\n`;\n fileContent += `const system = ${JSON.stringify(system, null, 2)};\\n`;\n fileContent += `const content = ${JSON.stringify(content, null, 2)};\\n`;\n fileContent += `const ai = ${JSON.stringify(ai, null, 2)};\\n`;\n fileContent += `const dictionary = ${JSON.stringify(dictionary, null, 2)};\\n`;\n fileContent += `const build = ${JSON.stringify(build, null, 2)};\\n`;\n fileContent += `const compiler = ${JSON.stringify(compiler, null, 2)};\\n`;\n\n if (format === 'esm') {\n fileContent += `\\nexport { internationalization, routing, editor, log, system, content, ai, dictionary, build, compiler };\\n`;\n } else {\n fileContent += `\\nmodule.exports.internationalization = internationalization;\\n`;\n fileContent += `module.exports.routing = routing;\\n`;\n fileContent += `module.exports.editor = editor;\\n`;\n fileContent += `module.exports.log = log;\\n`;\n fileContent += `module.exports.system = system;\\n`;\n fileContent += `module.exports.content = content;\\n`;\n fileContent += `module.exports.ai = ai;\\n`;\n fileContent += `module.exports.dictionary = dictionary;\\n`;\n fileContent += `module.exports.build = build;\\n`;\n fileContent += `module.exports.compiler = compiler;\\n`;\n }\n\n return fileContent;\n};\n"],"mappings":";AAEA,MAAa,gCACX,eACA,WACW;CACX,MAAM,EACJ,sBACA,SACA,QACA,KACA,QACA,SACA,IACA,YACA,OACA,aACE;CAEJ,IAAI,cAAc;AAElB,gBAAe,gCAAgC,KAAK,UAAU,sBAAsB,MAAM,EAAE,CAAC;AAC7F,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,eAAe,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC;AAC3D,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,cAAc,KAAK,UAAU,IAAI,MAAM,EAAE,CAAC;AACzD,gBAAe,sBAAsB,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;AACzE,gBAAe,iBAAiB,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;AAC/D,gBAAe,oBAAoB,KAAK,UAAU,UAAU,MAAM,EAAE,CAAC;AAErE,KAAI,WAAW,MACb,gBAAe;MACV;AACL,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;;AAGjB,QAAO"}
|
|
1
|
+
{"version":3,"file":"generateConfigurationContent.mjs","names":[],"sources":["../../../src/writeConfiguration/generateConfigurationContent.ts"],"sourcesContent":["import type { IntlayerConfig } from '@intlayer/types/config';\n\nexport const generateConfigurationContent = (\n configuration: IntlayerConfig,\n format: 'cjs' | 'esm'\n): string => {\n const {\n internationalization,\n routing,\n editor,\n analytics,\n log,\n system,\n content,\n ai,\n dictionary,\n build,\n compiler,\n } = configuration;\n\n let fileContent = '';\n\n fileContent += `const internationalization = ${JSON.stringify(internationalization, null, 2)};\\n`;\n fileContent += `const routing = ${JSON.stringify(routing, null, 2)};\\n`;\n fileContent += `const editor = ${JSON.stringify(editor, null, 2)};\\n`;\n fileContent += `const analytics = ${JSON.stringify(analytics, null, 2)};\\n`;\n fileContent += `const log = ${JSON.stringify(log, null, 2)};\\n`;\n fileContent += `const system = ${JSON.stringify(system, null, 2)};\\n`;\n fileContent += `const content = ${JSON.stringify(content, null, 2)};\\n`;\n fileContent += `const ai = ${JSON.stringify(ai, null, 2)};\\n`;\n fileContent += `const dictionary = ${JSON.stringify(dictionary, null, 2)};\\n`;\n fileContent += `const build = ${JSON.stringify(build, null, 2)};\\n`;\n fileContent += `const compiler = ${JSON.stringify(compiler, null, 2)};\\n`;\n\n if (format === 'esm') {\n fileContent += `\\nexport { internationalization, routing, editor, analytics, log, system, content, ai, dictionary, build, compiler };\\n`;\n } else {\n fileContent += `\\nmodule.exports.internationalization = internationalization;\\n`;\n fileContent += `module.exports.routing = routing;\\n`;\n fileContent += `module.exports.editor = editor;\\n`;\n fileContent += `module.exports.analytics = analytics;\\n`;\n fileContent += `module.exports.log = log;\\n`;\n fileContent += `module.exports.system = system;\\n`;\n fileContent += `module.exports.content = content;\\n`;\n fileContent += `module.exports.ai = ai;\\n`;\n fileContent += `module.exports.dictionary = dictionary;\\n`;\n fileContent += `module.exports.build = build;\\n`;\n fileContent += `module.exports.compiler = compiler;\\n`;\n }\n\n return fileContent;\n};\n"],"mappings":";AAEA,MAAa,gCACX,eACA,WACW;CACX,MAAM,EACJ,sBACA,SACA,QACA,WACA,KACA,QACA,SACA,IACA,YACA,OACA,aACE;CAEJ,IAAI,cAAc;AAElB,gBAAe,gCAAgC,KAAK,UAAU,sBAAsB,MAAM,EAAE,CAAC;AAC7F,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,qBAAqB,KAAK,UAAU,WAAW,MAAM,EAAE,CAAC;AACvE,gBAAe,eAAe,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC;AAC3D,gBAAe,kBAAkB,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AACjE,gBAAe,mBAAmB,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACnE,gBAAe,cAAc,KAAK,UAAU,IAAI,MAAM,EAAE,CAAC;AACzD,gBAAe,sBAAsB,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;AACzE,gBAAe,iBAAiB,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;AAC/D,gBAAe,oBAAoB,KAAK,UAAU,UAAU,MAAM,EAAE,CAAC;AAErE,KAAI,WAAW,MACb,gBAAe;MACV;AACL,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;AACf,iBAAe;;AAGjB,QAAO"}
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -16,6 +16,6 @@ import { PLATFORMS, PLATFORMS_METADATA, Platform, PlatformMetadata, SKILLS, SKIL
|
|
|
16
16
|
import { MCPTransport, installMCP } from "./installMCP/installMCP.js";
|
|
17
17
|
import { listDictionaries, listDictionariesWithStats } from "./listDictionariesPath.js";
|
|
18
18
|
import { DiffMode, ListGitFilesOptions, ListGitLinesOptions, listGitFiles, listGitLines } from "./listGitFiles.js";
|
|
19
|
-
import { ListProjectsOptions, listProjects } from "./listProjects.js";
|
|
19
|
+
import { ListProjectsOptions, getGitRootDir, listProjects } from "./listProjects.js";
|
|
20
20
|
import { logConfigDetails } from "./logConfigDetails.js";
|
|
21
|
-
export { type CmsCredentials, ContentStrategy, DictionaryStatus, DiffMode, InitOptions, ListGitFilesOptions, ListGitLinesOptions, ListProjectsOptions, MCPTransport, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, PLATFORMS, PLATFORMS_METADATA, type PackageManager, Platform, PlatformMetadata, type RoutingMode, SKILLS, SKILLS_METADATA, Skill, detectExportedComponentName, detectFormatCommand, detectPackageManager, enableEditorInConfig, getContentDeclarationFileTemplate, getDefaultApplicationURL, getInitialSkills, initIntlayer, installLSP, installMCP, installPackages, installSkills, listDictionaries, listDictionariesWithStats, listGitFiles, listGitLines, listProjects, logConfigDetails, prepareIntlayer, setupCmsCredentials, transformJSFile, writeCmsCredentialsToEnv, writeContentDeclaration, writeJSFile };
|
|
21
|
+
export { type CmsCredentials, ContentStrategy, DictionaryStatus, DiffMode, InitOptions, ListGitFilesOptions, ListGitLinesOptions, ListProjectsOptions, MCPTransport, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, PLATFORMS, PLATFORMS_METADATA, type PackageManager, Platform, PlatformMetadata, type RoutingMode, SKILLS, SKILLS_METADATA, Skill, detectExportedComponentName, detectFormatCommand, detectPackageManager, enableEditorInConfig, getContentDeclarationFileTemplate, getDefaultApplicationURL, getGitRootDir, getInitialSkills, initIntlayer, installLSP, installMCP, installPackages, installSkills, listDictionaries, listDictionariesWithStats, listGitFiles, listGitLines, listProjects, logConfigDetails, prepareIntlayer, setupCmsCredentials, transformJSFile, writeCmsCredentialsToEnv, writeContentDeclaration, writeJSFile };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/init/index.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/init/index.ts"],"mappings":";;;;;AA6LA;;;cAAa,wBAAA,GACX,YAAA,EAAc,MAAA;;AAsBhB;;;;;AAQA;;;KARY,eAAA;;;;KAQA,WAAA;EACV,WAAA,YAEA;EAAA,eAAA;EAMA;;;EAFA,iBAAA,YAqBA;EAnBA,iBAAA,YA0BA;EAxBA,KAAA;EA+BA;;;;EA1BA,gBAAA;EA6hCD;;;;;EAvhCC,gBAAA;EA0BuE;;;;;EApBvE,WAAA,GAAc,WAAA;;;;;;;EAOd,gBAAA,GAAmB,MAAA;;;;;;;EAOnB,eAAA,GAAkB,eAAA;AAAA;;;;cAMP,YAAA,GAAsB,OAAA,UAAiB,OAAA,GAAU,WAAA,KAAW,OAAA"}
|
|
@@ -6,14 +6,68 @@ type GithubWorkflowFile = {
|
|
|
6
6
|
/** Path relative to the project root, e.g. `.github/workflows/intlayer-fill.yml`. */filePath: string; /** Full YAML content of the workflow file. */
|
|
7
7
|
content: string;
|
|
8
8
|
};
|
|
9
|
+
/** Options controlling how the CI workflows are generated. */
|
|
10
|
+
type GithubWorkflowsOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* Route the intlayer commands through `intlayer ci` instead of calling them
|
|
13
|
+
* directly. The `ci` command discovers every Intlayer project of the
|
|
14
|
+
* repository (via `listProjects`) and runs the given command inside each of
|
|
15
|
+
* them, injecting per-project credentials from the
|
|
16
|
+
* `INTLAYER_PROJECT_CREDENTIALS` secret when provided. Required for
|
|
17
|
+
* monorepos where a single workflow must cover several projects.
|
|
18
|
+
*/
|
|
19
|
+
useCiCommand?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Repository-relative directory (posix separators) the workflow commands run
|
|
22
|
+
* in. Set when the Intlayer project lives in a subdirectory of the
|
|
23
|
+
* repository and the repository root has no workspace manifest to install
|
|
24
|
+
* dependencies from. Undefined = repository root.
|
|
25
|
+
*/
|
|
26
|
+
workingDirectory?: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Resolved placement and generation parameters for the CI workflows.
|
|
30
|
+
* See {@link resolveGithubWorkflowsContext}.
|
|
31
|
+
*/
|
|
32
|
+
type GithubWorkflowsContext = {
|
|
33
|
+
/**
|
|
34
|
+
* Directory the workflow files must be written to. GitHub only triggers
|
|
35
|
+
* workflows stored in `.github/workflows` at the repository root, so this is
|
|
36
|
+
* the git root whenever the project lives inside a git repository.
|
|
37
|
+
*/
|
|
38
|
+
workflowsRootDir: string; /** Package manager whose commands are baked into the workflows. */
|
|
39
|
+
packageManager: PackageManager; /** Generation options forwarded to {@link getGithubWorkflows}. */
|
|
40
|
+
options: GithubWorkflowsOptions;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Resolves where the CI workflows must be written and how their commands must
|
|
44
|
+
* be generated, based on the repository layout around `rootDir` (the Intlayer
|
|
45
|
+
* project being initialized):
|
|
46
|
+
*
|
|
47
|
+
* - Project at the repository root: workflows are written in place. When the
|
|
48
|
+
* repository is a monorepo (workspace manifest, or several Intlayer projects
|
|
49
|
+
* discovered by `listProjects`), the commands go through `intlayer ci` so
|
|
50
|
+
* every project is covered.
|
|
51
|
+
* - Project nested in a repository whose root has a `package.json`
|
|
52
|
+
* (workspace-managed monorepo): workflows are written at the git root —
|
|
53
|
+
* GitHub ignores `.github/workflows` in subdirectories — dependencies are
|
|
54
|
+
* installed at the root with the root's package manager, and the commands go
|
|
55
|
+
* through `intlayer ci` to iterate every Intlayer project.
|
|
56
|
+
* - Project nested in a repository without a root `package.json`: workflows
|
|
57
|
+
* are written at the git root but run inside the project directory
|
|
58
|
+
* (`working-directory`), keeping the project's own package manager.
|
|
59
|
+
*/
|
|
60
|
+
declare const resolveGithubWorkflowsContext: (rootDir: string, projectPackageManager: PackageManager) => Promise<GithubWorkflowsContext>;
|
|
9
61
|
/** Workflow file path constants, relative to the project root. */
|
|
10
62
|
declare const GITHUB_FILL_WORKFLOW_PATH = ".github/workflows/intlayer-fill.yml";
|
|
11
63
|
declare const GITHUB_TEST_WORKFLOW_PATH = ".github/workflows/intlayer-test.yml";
|
|
12
64
|
/**
|
|
13
65
|
* Returns the two Intlayer GitHub Actions workflows (`fill` and `test`),
|
|
14
|
-
* generated with commands matching the detected package manager
|
|
66
|
+
* generated with commands matching the detected package manager and the
|
|
67
|
+
* repository layout (see {@link GithubWorkflowsOptions} for the monorepo and
|
|
68
|
+
* nested-project variants).
|
|
15
69
|
*/
|
|
16
|
-
declare const getGithubWorkflows: (packageManager: PackageManager) => GithubWorkflowFile[];
|
|
70
|
+
declare const getGithubWorkflows: (packageManager: PackageManager, options?: GithubWorkflowsOptions) => GithubWorkflowFile[];
|
|
17
71
|
//#endregion
|
|
18
|
-
export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, getGithubWorkflows };
|
|
72
|
+
export { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, GithubWorkflowsContext, GithubWorkflowsOptions, getGithubWorkflows, resolveGithubWorkflowsContext };
|
|
19
73
|
//# sourceMappingURL=githubActions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubActions.d.ts","names":[],"sources":["../../../../src/init/utils/githubActions.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"githubActions.d.ts","names":[],"sources":["../../../../src/init/utils/githubActions.ts"],"mappings":";;;;KAMY,kBAAA;EAAA,qFAEV,QAAA;EAEA,OAAA;AAAA;AAIF;AAAA,KAAY,sBAAA;;;;AAuBZ;;;;;EAdE,YAAA;EAsBgB;;;;;AA2ClB;EA1DE,gBAAA;AAAA;;;;;KAOU,sBAAA;EAoDV;;;;;EA9CA,gBAAA,UAgD+B;EA9C/B,cAAA,EAAgB,cAAA,EA0VoB;EAxVpC,OAAA,EAAS,sBAAA;AAAA;;AAyVX;;;;;AAQA;;;;;;;;;;;;cAxTa,6BAAA,GACX,OAAA,UACA,qBAAA,EAAuB,cAAA,KACtB,OAAA,CAAQ,sBAAA;;cA4SE,yBAAA;AAAA,cACA,yBAAA;;;;;;;cAQA,kBAAA,GACX,cAAA,EAAgB,cAAA,EAChB,OAAA,GAAS,sBAAA,KACR,kBAAA"}
|
|
@@ -2,9 +2,9 @@ import { CompatSyncConfig, CompatVitePluginConfig, DetectMissingPackagesOptions,
|
|
|
2
2
|
import { RoutingMode, enableIntlayerEditorConfig, getMetroConfigTemplate, hasIntlayerVitePlugin, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n } from "./configManipulation.js";
|
|
3
3
|
import { ensureNamedImport, firstInsertIndex, isModuleScopeBinding } from "./astImports.js";
|
|
4
4
|
import { JsonLocalePattern, JsonLocalePatternType, LinguiCatalogPattern, NextIntlMessagesPattern, detectJsonLocalePattern, detectLinguiCatalogPattern, detectNextIntlMessagesPattern, ensureDirectory, exists, readFileFromRoot, writeFileToRoot } from "./fileSystem.js";
|
|
5
|
-
import { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, getGithubWorkflows } from "./githubActions.js";
|
|
5
|
+
import { GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, GithubWorkflowsContext, GithubWorkflowsOptions, getGithubWorkflows, resolveGithubWorkflowsContext } from "./githubActions.js";
|
|
6
6
|
import { parseJSONWithComments } from "./jsonParser.js";
|
|
7
7
|
import { NEXT_INTLAYER_BABEL_CONFIG_CONTENT, setupNextCompilerBabelConfig } from "./nextCompilerBabel.js";
|
|
8
8
|
import { findTsConfigFiles } from "./tsConfig.js";
|
|
9
9
|
import { isVersionAtLeast } from "./version.js";
|
|
10
|
-
export { CompatSyncConfig, CompatVitePluginConfig, DetectMissingPackagesOptions, GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, IntlayerPackageAnalysis, JsonLocalePattern, JsonLocalePatternType, LinguiCatalogPattern, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, NextIntlMessagesPattern, PackageManager, RoutingMode, detectJsonLocalePattern, detectLinguiCatalogPattern, detectMissingIntlayerPackages, detectNextIntlMessagesPattern, detectOutdatedIntlayerPackages, detectPackageManager, enableIntlayerEditorConfig, ensureDirectory, ensureNamedImport, exists, findTsConfigFiles, firstInsertIndex, getGithubWorkflows, getInstalledPackageVersion, getMetroConfigTemplate, hasIntlayerVitePlugin, installPackages, isIntlayerPackageName, isModuleScopeBinding, isVersionAtLeast, normalizeVersion, parseJSONWithComments, readFileFromRoot, replaceViteConfigPluginImportSource, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, setupNextCompilerBabelConfig, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, upgradePackages, writeFileToRoot };
|
|
10
|
+
export { CompatSyncConfig, CompatVitePluginConfig, DetectMissingPackagesOptions, GITHUB_FILL_WORKFLOW_PATH, GITHUB_TEST_WORKFLOW_PATH, GithubWorkflowFile, GithubWorkflowsContext, GithubWorkflowsOptions, IntlayerPackageAnalysis, JsonLocalePattern, JsonLocalePatternType, LinguiCatalogPattern, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, NextIntlMessagesPattern, PackageManager, RoutingMode, detectJsonLocalePattern, detectLinguiCatalogPattern, detectMissingIntlayerPackages, detectNextIntlMessagesPattern, detectOutdatedIntlayerPackages, detectPackageManager, enableIntlayerEditorConfig, ensureDirectory, ensureNamedImport, exists, findTsConfigFiles, firstInsertIndex, getGithubWorkflows, getInstalledPackageVersion, getMetroConfigTemplate, hasIntlayerVitePlugin, installPackages, isIntlayerPackageName, isModuleScopeBinding, isVersionAtLeast, normalizeVersion, parseJSONWithComments, readFileFromRoot, replaceViteConfigPluginImportSource, resolveGithubWorkflowsContext, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode, setupNextCompilerBabelConfig, updateAstroConfig, updateIntlayerConfigWithSyncPlugin, updateMetroConfig, updateNextConfig, updateNextConfigForNextI18next, updateNextConfigForNextIntl, updateNextConfigForNextTranslate, updateNuxtConfig, updateNuxtConfigForNuxtjsI18n, updateViteConfig, updateViteConfigForCompatPlugin, updateViteConfigForVueI18n, upgradePackages, writeFileToRoot };
|
|
@@ -11,6 +11,11 @@ type ListProjectsOptions = {
|
|
|
11
11
|
*/
|
|
12
12
|
gitRoot?: boolean;
|
|
13
13
|
};
|
|
14
|
+
/**
|
|
15
|
+
* Returns the git repository root directory, or `null` when the given
|
|
16
|
+
* directory is not inside a git repository.
|
|
17
|
+
*/
|
|
18
|
+
declare const getGitRootDir: (cwd?: string) => Promise<string | null>;
|
|
14
19
|
/**
|
|
15
20
|
* List all Intlayer projects by searching for configuration files
|
|
16
21
|
*
|
|
@@ -22,5 +27,5 @@ declare const listProjects: (options?: ListProjectsOptions) => Promise<{
|
|
|
22
27
|
projectsPath: string[];
|
|
23
28
|
}>;
|
|
24
29
|
//#endregion
|
|
25
|
-
export { ListProjectsOptions, listProjects };
|
|
30
|
+
export { ListProjectsOptions, getGitRootDir, listProjects };
|
|
26
31
|
//# sourceMappingURL=listProjects.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listProjects.d.ts","names":[],"sources":["../../src/listProjects.ts"],"mappings":";KAKY,mBAAA;EAAA;;;;EAKV,OAAA;
|
|
1
|
+
{"version":3,"file":"listProjects.d.ts","names":[],"sources":["../../src/listProjects.ts"],"mappings":";KAKY,mBAAA;EAAA;;;;EAKV,OAAA;EAYW;;;;EAPX,OAAA;AAAA;;;;;cAOW,aAAA,GAAuB,GAAA,cAAe,OAAA;;;;;;;cAgBtC,YAAA,GACX,OAAA,GAAU,mBAAA,KACT,OAAA;EAAU,SAAA;EAAmB,YAAA;AAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/engine",
|
|
3
|
-
"version": "9.0.0-canary.
|
|
3
|
+
"version": "9.0.0-canary.16",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Scans and builds Intlayer declaration files into dictionaries based on Intlayer configuration.",
|
|
6
6
|
"keywords": [
|
|
@@ -142,13 +142,13 @@
|
|
|
142
142
|
},
|
|
143
143
|
"dependencies": {
|
|
144
144
|
"@babel/parser": "7.29.7",
|
|
145
|
-
"@intlayer/api": "9.0.0-canary.
|
|
146
|
-
"@intlayer/config": "9.0.0-canary.
|
|
147
|
-
"@intlayer/core": "9.0.0-canary.
|
|
148
|
-
"@intlayer/dictionaries-entry": "9.0.0-canary.
|
|
149
|
-
"@intlayer/remote-dictionaries-entry": "9.0.0-canary.
|
|
150
|
-
"@intlayer/types": "9.0.0-canary.
|
|
151
|
-
"@intlayer/unmerged-dictionaries-entry": "9.0.0-canary.
|
|
145
|
+
"@intlayer/api": "9.0.0-canary.16",
|
|
146
|
+
"@intlayer/config": "9.0.0-canary.16",
|
|
147
|
+
"@intlayer/core": "9.0.0-canary.16",
|
|
148
|
+
"@intlayer/dictionaries-entry": "9.0.0-canary.16",
|
|
149
|
+
"@intlayer/remote-dictionaries-entry": "9.0.0-canary.16",
|
|
150
|
+
"@intlayer/types": "9.0.0-canary.16",
|
|
151
|
+
"@intlayer/unmerged-dictionaries-entry": "9.0.0-canary.16",
|
|
152
152
|
"@parcel/watcher": "2.5.6",
|
|
153
153
|
"defu": "6.1.7",
|
|
154
154
|
"fast-glob": "3.3.3",
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
"rimraf": "6.1.3",
|
|
165
165
|
"tsdown": "0.21.10",
|
|
166
166
|
"typescript": "6.0.3",
|
|
167
|
-
"vitest": "4.1.
|
|
167
|
+
"vitest": "4.1.10",
|
|
168
168
|
"zod": "4.4.3"
|
|
169
169
|
},
|
|
170
170
|
"engines": {
|