swallowkit 1.0.0-beta.60 → 1.0.0-beta.61
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.ja.md +3 -0
- package/README.md +3 -0
- package/dist/cli/commands/add-connector.d.ts.map +1 -1
- package/dist/cli/commands/add-connector.js +2 -1
- package/dist/cli/commands/add-connector.js.map +1 -1
- package/dist/cli/commands/create-model.js +1 -1
- package/dist/cli/commands/create-model.js.map +1 -1
- package/dist/cli/commands/init.d.ts +1 -5
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +45 -154
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/scaffold.js +1 -1
- package/dist/cli/commands/scaffold.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/project/agent-instructions.d.ts.map +1 -1
- package/dist/core/project/agent-instructions.js +2 -1
- package/dist/core/project/agent-instructions.js.map +1 -1
- package/dist/core/scaffold/model-parser.d.ts.map +1 -1
- package/dist/core/scaffold/model-parser.js +43 -92
- package/dist/core/scaffold/model-parser.js.map +1 -1
- package/dist/utils/package-manager.d.ts +4 -10
- package/dist/utils/package-manager.d.ts.map +1 -1
- package/dist/utils/package-manager.js +23 -15
- package/dist/utils/package-manager.js.map +1 -1
- package/package.json +8 -13
- package/src/__tests__/agent-instructions.test.ts +1 -1
- package/src/__tests__/connector-mock-server.test.ts +45 -25
- package/src/__tests__/init.test.ts +2 -50
- package/src/__tests__/model-parser.test.ts +61 -0
- package/src/__tests__/package-manager.test.ts +22 -5
- package/src/cli/commands/add-connector.ts +2 -1
- package/src/cli/commands/create-model.ts +1 -1
- package/src/cli/commands/init.ts +46 -173
- package/src/cli/commands/scaffold.ts +1 -1
- package/src/cli/index.ts +2 -0
- package/src/core/project/agent-instructions.ts +2 -2
- package/src/core/project/agent-templates/AGENTS.md +2 -0
- package/src/core/scaffold/model-parser.ts +40 -113
- package/src/utils/package-manager.ts +22 -17
|
@@ -221,7 +221,7 @@ export async function scaffoldCommand(options: ScaffoldOptions) {
|
|
|
221
221
|
console.log(
|
|
222
222
|
` ${options.apiOnly ? (backendLanguage === "typescript" ? "3" : "4") : (backendLanguage === "typescript" ? "5" : "6")}. Configure CosmosDBConnection in functions/local.settings.json`
|
|
223
223
|
);
|
|
224
|
-
console.log(` ${options.apiOnly ? (backendLanguage === "typescript" ? "4" : "5") : (backendLanguage === "typescript" ? "6" : "7")}. Run '${getCommands(detectFromProject()).
|
|
224
|
+
console.log(` ${options.apiOnly ? (backendLanguage === "typescript" ? "4" : "5") : (backendLanguage === "typescript" ? "6" : "7")}. Run '${getCommands(detectFromProject()).exec} swallowkit dev' to test the generated code`);
|
|
225
225
|
} catch (error: any) {
|
|
226
226
|
console.error("\n❌ Scaffold failed:", error.message);
|
|
227
227
|
process.exit(1);
|
package/src/cli/index.ts
CHANGED
|
@@ -109,6 +109,7 @@ export function createProgram(devCommandOverride: Command = devCommand): Command
|
|
|
109
109
|
.description("Initialize a new SwallowKit project")
|
|
110
110
|
.option("--template <template>", "Template to use", "default")
|
|
111
111
|
.option("--next-version <version>", "Next.js version to install (e.g., 16.0.7, latest)", "latest")
|
|
112
|
+
.option("--package-manager <manager>", "Package manager: npm | pnpm (defaults to invocation context)")
|
|
112
113
|
.option("--cicd <provider>", "CI/CD provider: github | azure | skip")
|
|
113
114
|
.option("--backend-language <language>", "Azure Functions backend language: typescript | csharp | python")
|
|
114
115
|
.option("--cosmos-db-mode <mode>", "Cosmos DB mode: freetier | serverless")
|
|
@@ -119,6 +120,7 @@ export function createProgram(devCommandOverride: Command = devCommand): Command
|
|
|
119
120
|
name: projectName || "swallowkit-app",
|
|
120
121
|
template: options.template,
|
|
121
122
|
nextVersion: options.nextVersion,
|
|
123
|
+
packageManager: options.packageManager,
|
|
122
124
|
cicd: options.cicd,
|
|
123
125
|
backendLanguage: options.backendLanguage,
|
|
124
126
|
cosmosDbMode: options.cosmosDbMode,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { BackendLanguage } from "../../types";
|
|
4
|
-
import { PackageManager } from "../../utils/package-manager";
|
|
4
|
+
import { PackageManager, getCommands } from "../../utils/package-manager";
|
|
5
5
|
|
|
6
6
|
export interface AgentInstructionContext {
|
|
7
7
|
projectName: string;
|
|
@@ -74,7 +74,7 @@ function getBackendRules(backendLanguage: BackendLanguage): string {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
function interpolateTemplate(template: string, context: AgentInstructionContext): string {
|
|
77
|
-
const runCmd = context.packageManager
|
|
77
|
+
const runCmd = getCommands(context.packageManager).exec;
|
|
78
78
|
const replacements: Record<string, string> = {
|
|
79
79
|
projectName: context.projectName,
|
|
80
80
|
backendLanguageLabel: BACKEND_LANGUAGE_LABELS[context.backendLanguage],
|
|
@@ -500,3 +500,5 @@ Do:
|
|
|
500
500
|
- keep specifications focused on intent and observable behavior
|
|
501
501
|
- prefer vertical, independently verifiable slices
|
|
502
502
|
- verify before final semantic review
|
|
503
|
+
|
|
504
|
+
Use `{{pm}}`, the package manager selected for this project. Do not introduce another package manager or lockfile. Use `{{runCmd}} swallowkit` for the project-local CLI. The MCP launcher intentionally resolves `latest` independently.
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import * as fs from "fs";
|
|
6
6
|
import { execFileSync } from "child_process";
|
|
7
7
|
import * as path from "path";
|
|
8
|
+
import * as ts from "typescript";
|
|
8
9
|
|
|
9
10
|
import { ModelConnectorConfig, ModelAuthPolicy } from "../../types";
|
|
10
11
|
|
|
@@ -324,61 +325,36 @@ function mergeNestedSchemaInfo(fields: FieldInfo[], nestedRefs: NestedSchemaRef[
|
|
|
324
325
|
}
|
|
325
326
|
}
|
|
326
327
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
);
|
|
358
|
-
|
|
359
|
-
// 外部パッケージのインポートを除去
|
|
360
|
-
content = content.replace(/import\s+.*?\s+from\s+['"](?!\.).*?['"];?\s*/g, '');
|
|
361
|
-
// export キーワードを除去
|
|
362
|
-
content = content.replace(/export\s+(const|type|interface|class|function)\s+/g, '$1 ');
|
|
363
|
-
// 型宣言を除去(ランタイムでは不要)
|
|
364
|
-
content = content.replace(/^type\s+\w+\s*=\s*[^;]+;/gm, '');
|
|
365
|
-
content = content.replace(/^interface\s+\w+\s*\{[\s\S]*?\}/gm, '');
|
|
366
|
-
// コメントを除去
|
|
367
|
-
content = content.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
368
|
-
content = content.replace(/\/\/.*/g, '');
|
|
369
|
-
|
|
370
|
-
// 直接インポートされていない const 宣言を除去(displayName 等の重複を防ぐ)
|
|
371
|
-
if (importedNames) {
|
|
372
|
-
content = content.replace(/^const\s+(\w+)\s*=\s*[^;]+;/gm, (constMatch: string, varName: string) => {
|
|
373
|
-
return importedNames.has(varName) ? constMatch : '';
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
return [...transitiveParts, content.trim()].filter(Boolean).join('\n\n');
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
function resolveBundledTsxCliPath(): string {
|
|
381
|
-
return require.resolve("tsx/cli");
|
|
328
|
+
function compileModelModule(modelPath: string, directory: string, modules = new Map<string, string>()): string {
|
|
329
|
+
const sourcePath = path.resolve(modelPath);
|
|
330
|
+
const existing = modules.get(sourcePath);
|
|
331
|
+
if (existing) return existing;
|
|
332
|
+
const outputPath = path.join(directory, `model-${modules.size}.mjs`);
|
|
333
|
+
modules.set(sourcePath, outputPath);
|
|
334
|
+
const output = ts.transpileModule(fs.readFileSync(sourcePath, "utf8"), {
|
|
335
|
+
fileName: sourcePath,
|
|
336
|
+
compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ESNext },
|
|
337
|
+
transformers: {
|
|
338
|
+
after: [context => source => {
|
|
339
|
+
const visit: ts.Visitor = node => {
|
|
340
|
+
if (ts.isStringLiteral(node) &&
|
|
341
|
+
(ts.isImportDeclaration(node.parent) || ts.isExportDeclaration(node.parent)) &&
|
|
342
|
+
node.text.startsWith(".")) {
|
|
343
|
+
const base = path.resolve(path.dirname(sourcePath), node.text);
|
|
344
|
+
const candidates = [base.replace(/\.js$/, ".ts"), `${base}.ts`, path.join(base, "index.ts"), base];
|
|
345
|
+
const dependency = candidates.find(candidate => fs.existsSync(candidate) && fs.statSync(candidate).isFile());
|
|
346
|
+
if (!dependency) throw new Error(`Cannot resolve ${node.text} from ${sourcePath}`);
|
|
347
|
+
const compiled = compileModelModule(dependency, directory, modules);
|
|
348
|
+
return context.factory.createStringLiteral(`./${path.basename(compiled)}`);
|
|
349
|
+
}
|
|
350
|
+
return ts.visitEachChild(node, visit, context);
|
|
351
|
+
};
|
|
352
|
+
return ts.visitNode(source, visit) as ts.SourceFile;
|
|
353
|
+
}],
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
fs.writeFileSync(outputPath, output.outputText);
|
|
357
|
+
return outputPath;
|
|
382
358
|
}
|
|
383
359
|
|
|
384
360
|
/**
|
|
@@ -386,53 +362,9 @@ function resolveBundledTsxCliPath(): string {
|
|
|
386
362
|
*/
|
|
387
363
|
async function extractFieldsFromSchema(modelPath: string, schemaName: string): Promise<FieldInfo[]> {
|
|
388
364
|
const fields: FieldInfo[] = [];
|
|
365
|
+
let tempDirectory: string | undefined;
|
|
389
366
|
|
|
390
367
|
try {
|
|
391
|
-
// モデルファイルの内容を読み込む
|
|
392
|
-
let modelContent = fs.readFileSync(modelPath, 'utf8');
|
|
393
|
-
const modelDir = path.dirname(path.resolve(modelPath));
|
|
394
|
-
|
|
395
|
-
// ローカル相対インポートを再帰的にインライン化して保持
|
|
396
|
-
// パターン: import { categorySchema } from './category'
|
|
397
|
-
const seenPaths = new Set<string>([path.resolve(modelPath)]);
|
|
398
|
-
const localImports: string[] = [];
|
|
399
|
-
modelContent = modelContent.replace(
|
|
400
|
-
/import\s*\{([^}]+)\}\s*from\s*['"](\.[^'"]+)['"]\s*;?/g,
|
|
401
|
-
(_match: string, imports: string, importPath: string) => {
|
|
402
|
-
// インポートされた変数名を取得
|
|
403
|
-
const importedNames = new Set(
|
|
404
|
-
imports.split(',').map(s => s.trim().split(/\s+as\s+/).pop()!.trim()).filter(s => s.length > 0)
|
|
405
|
-
);
|
|
406
|
-
|
|
407
|
-
// 相対パスを絶対パスに解決
|
|
408
|
-
let resolvedPath = path.resolve(modelDir, importPath);
|
|
409
|
-
if (!resolvedPath.endsWith('.ts') && !resolvedPath.endsWith('.js')) {
|
|
410
|
-
resolvedPath += '.ts';
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// 推移的なローカル依存を含めて再帰的にインライン化
|
|
414
|
-
const inlined = inlineLocalDeps(resolvedPath, importedNames, seenPaths);
|
|
415
|
-
if (inlined) localImports.push(inlined);
|
|
416
|
-
return ''; // 元のインポート文は除去
|
|
417
|
-
}
|
|
418
|
-
);
|
|
419
|
-
|
|
420
|
-
// zod 以外のパッケージインポートを除去
|
|
421
|
-
modelContent = modelContent.replace(/import\s+.*?\s+from\s+['"].*?['"];?\s*/g, '');
|
|
422
|
-
modelContent = modelContent.replace(/export\s+(const|type|interface|class|function)\s+/g, '$1 ');
|
|
423
|
-
// type宣言を削除(ランタイムでは不要)
|
|
424
|
-
modelContent = modelContent.replace(/^type\s+\w+\s*=\s*[^;]+;/gm, '');
|
|
425
|
-
// interface宣言を削除(ランタイムでは不要、複数行対応)
|
|
426
|
-
modelContent = modelContent.replace(/^interface\s+\w+\s*\{[\s\S]*?\}/gm, '');
|
|
427
|
-
// コメントを削除
|
|
428
|
-
modelContent = modelContent.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
429
|
-
modelContent = modelContent.replace(/\/\/.*/g, '');
|
|
430
|
-
// TypeScript の `as const` アサーションを削除(.mjs では構文エラーになる)
|
|
431
|
-
modelContent = modelContent.replace(/\s+as\s+const\b/g, '');
|
|
432
|
-
|
|
433
|
-
// インライン化したローカルインポートを先頭に追加
|
|
434
|
-
const inlinedDeps = localImports.length > 0 ? localImports.join('\n\n') + '\n\n' : '';
|
|
435
|
-
|
|
436
368
|
// プロジェクトルートを探す(package.jsonがある場所)
|
|
437
369
|
let projectRoot = path.dirname(modelPath);
|
|
438
370
|
while (projectRoot !== path.dirname(projectRoot)) {
|
|
@@ -443,16 +375,11 @@ async function extractFieldsFromSchema(modelPath: string, schemaName: string): P
|
|
|
443
375
|
}
|
|
444
376
|
|
|
445
377
|
// プロジェクトルート内に一時スクリプトファイルを作成
|
|
446
|
-
|
|
378
|
+
tempDirectory = fs.mkdtempSync(path.join(projectRoot, '.swallowkit-parser-'));
|
|
379
|
+
const compiledModel = compileModelModule(modelPath, tempDirectory);
|
|
380
|
+
const tempScript = path.join(tempDirectory, 'inspect.mjs');
|
|
447
381
|
const scriptCode = `
|
|
448
|
-
import {
|
|
449
|
-
|
|
450
|
-
// インライン化した依存スキーマ
|
|
451
|
-
${inlinedDeps}
|
|
452
|
-
// モデルファイルの内容を評価
|
|
453
|
-
${modelContent}
|
|
454
|
-
|
|
455
|
-
const schema = ${schemaName};
|
|
382
|
+
import { ${schemaName} as schema } from './${path.basename(compiledModel)}';
|
|
456
383
|
|
|
457
384
|
// Zod v3とv4の両方に対応
|
|
458
385
|
const isObject = (schema && schema._def &&
|
|
@@ -501,7 +428,7 @@ if (isObject) {
|
|
|
501
428
|
// ZodArray をチェック
|
|
502
429
|
if (getTypeName(fieldDef) === 'ZodArray') {
|
|
503
430
|
isArray = true;
|
|
504
|
-
fieldDef = fieldDef._def.
|
|
431
|
+
fieldDef = fieldDef._def.element || fieldDef._def.type;
|
|
505
432
|
}
|
|
506
433
|
|
|
507
434
|
// 基本型を判定
|
|
@@ -552,8 +479,7 @@ if (isObject) {
|
|
|
552
479
|
fs.writeFileSync(tempScript, scriptCode, 'utf8');
|
|
553
480
|
|
|
554
481
|
try {
|
|
555
|
-
const
|
|
556
|
-
const result = execFileSync(process.execPath, [tsxCliPath, tempScript], {
|
|
482
|
+
const result = execFileSync(process.execPath, [tempScript], {
|
|
557
483
|
encoding: 'utf8',
|
|
558
484
|
cwd: projectRoot,
|
|
559
485
|
});
|
|
@@ -573,10 +499,11 @@ if (isObject) {
|
|
|
573
499
|
}
|
|
574
500
|
}
|
|
575
501
|
} catch (error) {
|
|
576
|
-
// tsxが使えない場合は正規表現フォールバック
|
|
577
502
|
console.warn('Failed to use dynamic import, falling back to regex parsing');
|
|
578
503
|
console.warn('Error:', error);
|
|
579
504
|
return extractFieldsWithRegex(modelPath, schemaName);
|
|
505
|
+
} finally {
|
|
506
|
+
if (tempDirectory) fs.rmSync(tempDirectory, { recursive: true, force: true });
|
|
580
507
|
}
|
|
581
508
|
|
|
582
509
|
return fields;
|
|
@@ -30,13 +30,13 @@ export interface PackageManagerCommands {
|
|
|
30
30
|
dlx: string;
|
|
31
31
|
/** Run a script: "pnpm run" / "npm run" */
|
|
32
32
|
run: string;
|
|
33
|
-
/** Run a script with filter: "pnpm
|
|
33
|
+
/** Run a script with filter: "pnpm --filter <ws> run" / "npm run --workspace=<ws>" */
|
|
34
34
|
runFilter: (workspace: string) => string;
|
|
35
35
|
/** Start script: "pnpm start" / "npm start" */
|
|
36
36
|
start: string;
|
|
37
37
|
/** Install production only (in temp dir for CI): "pnpm install --prod" / "npm install --omit=dev" */
|
|
38
38
|
installProd: string;
|
|
39
|
-
/** create-next-app flag: "--use-pnpm" /
|
|
39
|
+
/** create-next-app flag: "--use-pnpm" / "--use-npm" */
|
|
40
40
|
createNextAppFlag: string | null;
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -55,9 +55,9 @@ export function getCommands(pm: PackageManager): PackageManagerCommands {
|
|
|
55
55
|
exec: "pnpm exec",
|
|
56
56
|
dlx: "pnpm dlx",
|
|
57
57
|
run: "pnpm run",
|
|
58
|
-
runFilter: (ws) => `pnpm
|
|
58
|
+
runFilter: (ws) => `pnpm --filter ${ws} run`,
|
|
59
59
|
start: "pnpm start",
|
|
60
|
-
installProd: "pnpm install --prod",
|
|
60
|
+
installProd: "pnpm install --prod --no-frozen-lockfile",
|
|
61
61
|
createNextAppFlag: "--use-pnpm",
|
|
62
62
|
};
|
|
63
63
|
}
|
|
@@ -76,22 +76,19 @@ export function getCommands(pm: PackageManager): PackageManagerCommands {
|
|
|
76
76
|
runFilter: (ws) => `npm run --workspace=${ws}`,
|
|
77
77
|
start: "npm start",
|
|
78
78
|
installProd: "npm install --omit=dev",
|
|
79
|
-
createNextAppFlag:
|
|
79
|
+
createNextAppFlag: "--use-npm",
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Detect the preferred package manager for new project initialisation.
|
|
85
85
|
*
|
|
86
|
-
*
|
|
87
|
-
* 1. If pnpm is installed on the system → always use pnpm
|
|
88
|
-
* (even when invoked via `npx`, since `npx` is often used out of habit)
|
|
89
|
-
* 2. Otherwise → npm
|
|
90
|
-
*
|
|
91
|
-
* This is intentionally independent of `npm_config_user_agent` so that
|
|
92
|
-
* `npx swallowkit init` still creates a pnpm project when pnpm is available.
|
|
86
|
+
* Honor the invoking package manager before falling back to available binaries.
|
|
93
87
|
*/
|
|
94
88
|
export function detectFromUserAgent(pnpmIsInstalled: () => boolean = isPnpmInstalled): PackageManager {
|
|
89
|
+
const agent = process.env.npm_config_user_agent || "";
|
|
90
|
+
if (agent.startsWith("pnpm/")) return "pnpm";
|
|
91
|
+
if (agent.startsWith("npm/")) return "npm";
|
|
95
92
|
return pnpmIsInstalled() ? "pnpm" : "npm";
|
|
96
93
|
}
|
|
97
94
|
|
|
@@ -111,11 +108,18 @@ function isPnpmInstalled(): boolean {
|
|
|
111
108
|
* Detect the package manager used in an existing project directory
|
|
112
109
|
* by checking for lockfiles.
|
|
113
110
|
*
|
|
114
|
-
* Priority:
|
|
111
|
+
* Priority: explicit project metadata > lockfiles > workspace config > invocation/binaries
|
|
115
112
|
*/
|
|
116
113
|
export function detectFromProject(projectDir?: string): PackageManager {
|
|
117
114
|
const dir = projectDir || process.cwd();
|
|
118
115
|
|
|
116
|
+
const manifestPath = path.join(dir, "package.json");
|
|
117
|
+
if (fs.existsSync(manifestPath)) {
|
|
118
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
119
|
+
const manager = manifest.devEngines?.packageManager?.name || manifest.packageManager?.split("@")[0];
|
|
120
|
+
if (manager === "npm" || manager === "pnpm") return manager;
|
|
121
|
+
}
|
|
122
|
+
|
|
119
123
|
if (fs.existsSync(path.join(dir, "pnpm-lock.yaml"))) {
|
|
120
124
|
return "pnpm";
|
|
121
125
|
}
|
|
@@ -124,6 +128,7 @@ export function detectFromProject(projectDir?: string): PackageManager {
|
|
|
124
128
|
}
|
|
125
129
|
|
|
126
130
|
// No lockfile found — fall back to user agent detection
|
|
131
|
+
if (fs.existsSync(path.join(dir, "pnpm-workspace.yaml"))) return "pnpm";
|
|
127
132
|
return detectFromUserAgent();
|
|
128
133
|
}
|
|
129
134
|
|
|
@@ -151,7 +156,7 @@ export function getWorkspaceConfig(pm: PackageManager, workspaces: string[]) {
|
|
|
151
156
|
/** pnpm uses pnpm-workspace.yaml */
|
|
152
157
|
type: "file" as const,
|
|
153
158
|
filename: "pnpm-workspace.yaml",
|
|
154
|
-
content: `packages:\n${workspaces.map((w) => ` - ${w}`).join("\n")}\n`,
|
|
159
|
+
content: `packages:\n${workspaces.map((w) => ` - ${w}`).join("\n")}\nallowBuilds:\n protobufjs: false\n unrs-resolver: false\n`,
|
|
155
160
|
};
|
|
156
161
|
}
|
|
157
162
|
|
|
@@ -171,7 +176,7 @@ export function getCiSetupStep(pm: PackageManager): string {
|
|
|
171
176
|
return ` - name: Setup pnpm
|
|
172
177
|
uses: pnpm/action-setup@v4
|
|
173
178
|
with:
|
|
174
|
-
version:
|
|
179
|
+
version: 11`;
|
|
175
180
|
}
|
|
176
181
|
// npm: no extra setup needed (comes with Node.js)
|
|
177
182
|
return "";
|
|
@@ -199,7 +204,7 @@ export function getAzurePipelinesSetup(pm: PackageManager): string {
|
|
|
199
204
|
if (pm === "pnpm") {
|
|
200
205
|
return ` - script: |
|
|
201
206
|
corepack enable
|
|
202
|
-
corepack prepare pnpm@
|
|
207
|
+
corepack prepare pnpm@11 --activate
|
|
203
208
|
displayName: 'Setup pnpm'`;
|
|
204
209
|
}
|
|
205
210
|
// npm: no extra step needed
|
|
@@ -213,7 +218,7 @@ export function getBuildScript(pm: PackageManager): string {
|
|
|
213
218
|
const copyStandaloneAssets = `node -e "const fs=require('fs');fs.mkdirSync('.next/standalone/.next',{recursive:true});if(fs.existsSync('.next/static'))fs.cpSync('.next/static','.next/standalone/.next/static',{recursive:true});if(fs.existsSync('public'))fs.cpSync('public','.next/standalone/public',{recursive:true});"`;
|
|
214
219
|
|
|
215
220
|
if (pm === "pnpm") {
|
|
216
|
-
return `pnpm
|
|
221
|
+
return `pnpm --filter shared run build && next build --webpack && ${copyStandaloneAssets}`;
|
|
217
222
|
}
|
|
218
223
|
return `npm run --workspace=shared build && next build --webpack && ${copyStandaloneAssets}`;
|
|
219
224
|
}
|