@codyswann/lisa 1.10.0 → 1.11.0
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 +71 -0
- package/all/copy-overwrite/.claude/agents/skill-evaluator.md +4 -4
- package/all/copy-overwrite/CLAUDE.md +1 -1
- package/cdk/tagged-merge/package.lisa.json +31 -0
- package/dist/core/config.d.ts +1 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +1 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +2 -0
- package/dist/core/lisa.js.map +1 -1
- package/dist/strategies/index.d.ts +1 -0
- package/dist/strategies/index.d.ts.map +1 -1
- package/dist/strategies/index.js +3 -0
- package/dist/strategies/index.js.map +1 -1
- package/dist/strategies/package-lisa-types.d.ts +83 -0
- package/dist/strategies/package-lisa-types.d.ts.map +1 -0
- package/dist/strategies/package-lisa-types.js +10 -0
- package/dist/strategies/package-lisa-types.js.map +1 -0
- package/dist/strategies/package-lisa.d.ts +183 -0
- package/dist/strategies/package-lisa.d.ts.map +1 -0
- package/dist/strategies/package-lisa.js +385 -0
- package/dist/strategies/package-lisa.js.map +1 -0
- package/expo/copy-overwrite/knip.json +0 -1
- package/expo/tagged-merge/package.lisa.json +131 -0
- package/nestjs/tagged-merge/package.lisa.json +73 -0
- package/package.json +2 -10
- package/typescript/copy-overwrite/knip.json +3 -2
- package/typescript/tagged-merge/package.lisa.json +73 -0
- package/cdk/tagged-merge/package.json +0 -37
- package/expo/tagged-merge/package.json +0 -145
- package/nestjs/tagged-merge/package.json +0 -87
- package/typescript/tagged-merge/package.json +0 -76
- /package/cdk/{copy-overwrite → create-only}/.github/workflows/ci.yml +0 -0
- /package/cdk/{copy-overwrite → create-only}/.github/workflows/deploy.yml +0 -0
- /package/expo/{copy-overwrite → create-only}/.github/workflows/ci.yml +0 -0
- /package/expo/{copy-overwrite → create-only}/.github/workflows/deploy.yml +0 -0
- /package/nestjs/{copy-overwrite → create-only}/.github/workflows/ci.yml +0 -0
- /package/nestjs/{copy-overwrite → create-only}/.github/workflows/deploy.yml +0 -0
- /package/typescript/{copy-overwrite → create-only}/.github/workflows/ci.yml +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import type { FileOperationResult } from "../core/config.js";
|
|
2
|
+
import type { ICopyStrategy, StrategyContext } from "./strategy.interface.js";
|
|
3
|
+
/**
|
|
4
|
+
* @file package-lisa.ts
|
|
5
|
+
* @description Package.lisa.json strategy for governance-driven package.json management
|
|
6
|
+
*
|
|
7
|
+
* Implements a two-file approach to package.json governance:
|
|
8
|
+
* - Source: package.lisa.json files in type directories (all/, typescript/, expo/, etc.)
|
|
9
|
+
* - Destination: project's package.json
|
|
10
|
+
*
|
|
11
|
+
* Behavior is defined in package.lisa.json:
|
|
12
|
+
* - force: Lisa's values completely replace project's values
|
|
13
|
+
* - defaults: Project's values preserved; Lisa's used only if missing
|
|
14
|
+
* - merge: Arrays concatenated and deduplicated
|
|
15
|
+
*
|
|
16
|
+
* Inheritance chain: all → typescript → specific types (expo, nestjs, cdk, npm-package)
|
|
17
|
+
* Child types override parent values in each section.
|
|
18
|
+
* @module strategies
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Package.lisa.json strategy: Manage package.json via separate template files
|
|
22
|
+
* - Loads templates from all applicable types in inheritance chain
|
|
23
|
+
* - Merges templates (child overrides parent)
|
|
24
|
+
* - Applies force/defaults/merge logic to project's package.json
|
|
25
|
+
* - Keeps project's package.json 100% clean (no Lisa artifacts)
|
|
26
|
+
*/
|
|
27
|
+
export declare class PackageLisaStrategy implements ICopyStrategy {
|
|
28
|
+
readonly name: "package-lisa";
|
|
29
|
+
private readonly PACKAGE_JSON;
|
|
30
|
+
private readonly TSCONFIG_JSON;
|
|
31
|
+
private readonly APP_JSON;
|
|
32
|
+
private readonly EAS_JSON;
|
|
33
|
+
private readonly NEST_CLI_JSON;
|
|
34
|
+
private readonly CDK_JSON;
|
|
35
|
+
/**
|
|
36
|
+
* Apply package-lisa strategy: Load templates from inheritance chain, apply to package.json
|
|
37
|
+
* @remarks
|
|
38
|
+
* This strategy is unique because:
|
|
39
|
+
* 1. It loads multiple source files from type hierarchy, not just one
|
|
40
|
+
* 2. It applies structured merge logic (force/defaults/merge) instead of simple JSON merge
|
|
41
|
+
* 3. It never applies changes if source file doesn't exist in ANY type directory
|
|
42
|
+
* @param sourcePath - Path to source package.lisa.json (only used for detecting when to apply)
|
|
43
|
+
* @param destPath - Destination package.json path
|
|
44
|
+
* @param relativePath - Relative path for recording ("package.json")
|
|
45
|
+
* @param context - Strategy context with config and callbacks
|
|
46
|
+
* @returns Result with action "copied", "merged", or "skipped"
|
|
47
|
+
*/
|
|
48
|
+
apply(sourcePath: string, destPath: string, relativePath: string, context: StrategyContext): Promise<FileOperationResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Create destination file when it doesn't exist
|
|
51
|
+
* @param destPath - Path to destination package.json
|
|
52
|
+
* @param merged - Merged package.json object
|
|
53
|
+
* @param relativePath - Relative path for recording
|
|
54
|
+
* @param context - Strategy context with config and callbacks
|
|
55
|
+
* @returns Result with action "copied"
|
|
56
|
+
* @private
|
|
57
|
+
*/
|
|
58
|
+
private createDestination;
|
|
59
|
+
/**
|
|
60
|
+
* Update destination file when it exists
|
|
61
|
+
* @param destPath - Path to destination package.json
|
|
62
|
+
* @param merged - Merged package.json object
|
|
63
|
+
* @param relativePath - Relative path for recording
|
|
64
|
+
* @param context - Strategy context with config and callbacks
|
|
65
|
+
* @returns Result with action "merged" or "skipped"
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
private updateDestination;
|
|
69
|
+
/**
|
|
70
|
+
* Merge package.json using force/defaults/merge logic from package.lisa.json templates
|
|
71
|
+
* @param packageJsonPath - Absolute path to destination package.json
|
|
72
|
+
* @param context - Strategy context with Lisa config
|
|
73
|
+
* @returns Merged package.json object
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
private mergePackageJson;
|
|
77
|
+
/**
|
|
78
|
+
* Detect which project types apply to this project
|
|
79
|
+
* (TypeScript, Expo, NestJS, CDK, npm-package)
|
|
80
|
+
* @param projectDir - Root directory of the project
|
|
81
|
+
* @returns Array of detected project types
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
private detectProjectTypes;
|
|
85
|
+
/**
|
|
86
|
+
* Check if package.json contains a key
|
|
87
|
+
* @param projectDir - The project directory to check
|
|
88
|
+
* @param key - The key to check for in package.json
|
|
89
|
+
* @returns True if the key exists in package.json, false otherwise
|
|
90
|
+
* @private
|
|
91
|
+
*/
|
|
92
|
+
private packageJsonHasKey;
|
|
93
|
+
/**
|
|
94
|
+
* Check if package.json contains a key that starts with a prefix (for scoped packages)
|
|
95
|
+
* @param projectDir - The project directory to check
|
|
96
|
+
* @param prefix - The prefix to check for (e.g., "@nestjs" or "@aws-sdk")
|
|
97
|
+
* @returns True if any key in package.json starts with the given prefix, false otherwise
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
100
|
+
private packageJsonHasKeyPrefix;
|
|
101
|
+
/**
|
|
102
|
+
* Get a field value from package.json
|
|
103
|
+
* @param projectDir - The project directory containing the package.json
|
|
104
|
+
* @param fieldName - The field name to retrieve from package.json
|
|
105
|
+
* @returns The field value if found, undefined if not found or if package.json doesn't exist
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
private packageJsonField;
|
|
109
|
+
/**
|
|
110
|
+
* Load and merge all package.lisa.json templates from type hierarchy
|
|
111
|
+
* @remarks
|
|
112
|
+
* Inheritance chain: all → typescript → specific types (expo, nestjs, cdk, npm-package)
|
|
113
|
+
* Child types override parent types in force, defaults, and merge sections.
|
|
114
|
+
* @param lisaDir - Root Lisa directory path
|
|
115
|
+
* @param detectedTypes - Project types to load templates for
|
|
116
|
+
* @returns Merged template with force, defaults, merge sections
|
|
117
|
+
* @private
|
|
118
|
+
*/
|
|
119
|
+
private loadAndMergeTemplates;
|
|
120
|
+
/**
|
|
121
|
+
* Expand project types to include parent types
|
|
122
|
+
* @remarks
|
|
123
|
+
* Type hierarchy: expo/nestjs/cdk/npm-package inherit from typescript
|
|
124
|
+
* This expands a list to include parents.
|
|
125
|
+
* Example: [expo] → [typescript, expo]
|
|
126
|
+
* @param types - Project types detected
|
|
127
|
+
* @returns Expanded types including parents
|
|
128
|
+
* @private
|
|
129
|
+
*/
|
|
130
|
+
private expandTypeHierarchy;
|
|
131
|
+
/**
|
|
132
|
+
* Merge two template objects
|
|
133
|
+
* Child template (override) values win in force and defaults.
|
|
134
|
+
* Merge arrays are concatenated without deduplication at merge time.
|
|
135
|
+
* @param parent - Parent template (e.g., "all" or "typescript")
|
|
136
|
+
* @param child - Child template (e.g., "expo") that overrides parent
|
|
137
|
+
* @returns Merged template
|
|
138
|
+
* @private
|
|
139
|
+
*/
|
|
140
|
+
private mergeTemplates;
|
|
141
|
+
/**
|
|
142
|
+
* Merge two merge-section objects
|
|
143
|
+
* Arrays are concatenated (deduplication happens later when applied to package.json)
|
|
144
|
+
* @param parent - Parent merge sections
|
|
145
|
+
* @param child - Child merge sections
|
|
146
|
+
* @returns Merged sections
|
|
147
|
+
* @private
|
|
148
|
+
*/
|
|
149
|
+
private mergeMergeSections;
|
|
150
|
+
/**
|
|
151
|
+
* Apply force/defaults/merge logic to project's package.json
|
|
152
|
+
* @remarks
|
|
153
|
+
* Processing order:
|
|
154
|
+
* 1. Apply force: Deep merge with Lisa values winning (entire section replaced)
|
|
155
|
+
* 2. Apply defaults: Deep merge with project values winning (only set if missing)
|
|
156
|
+
* 3. Apply merge: Concatenate arrays and deduplicate
|
|
157
|
+
* @param projectJson - Current project's package.json
|
|
158
|
+
* @param template - Merged package.lisa.json template
|
|
159
|
+
* @returns Modified package.json
|
|
160
|
+
* @private
|
|
161
|
+
*/
|
|
162
|
+
private applyTemplate;
|
|
163
|
+
/**
|
|
164
|
+
* Apply merge-section arrays to package.json
|
|
165
|
+
* Concatenates Lisa's items and project's items, deduplicated by JSON.stringify equality.
|
|
166
|
+
* @param packageJson - Current package.json after force/defaults applied
|
|
167
|
+
* @param mergeSections - Merge sections from template
|
|
168
|
+
* @returns Package.json with merge sections applied
|
|
169
|
+
* @private
|
|
170
|
+
*/
|
|
171
|
+
private applyMergeSections;
|
|
172
|
+
/**
|
|
173
|
+
* Concatenate two arrays and remove duplicates
|
|
174
|
+
* Uses JSON.stringify for value equality comparison.
|
|
175
|
+
* Lisa items come first, then project's unique items.
|
|
176
|
+
* @param lisaItems - Lisa's items (come first)
|
|
177
|
+
* @param projectItems - Project's items (added if not already present)
|
|
178
|
+
* @returns Deduplicated array
|
|
179
|
+
* @private
|
|
180
|
+
*/
|
|
181
|
+
private deduplicateArrays;
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=package-lisa.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-lisa.d.ts","sourceRoot":"","sources":["../../src/strategies/package-lisa.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAe,MAAM,mBAAmB,CAAC;AAE1E,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAc9E;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;GAMG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IACvD,QAAQ,CAAC,IAAI,EAAG,cAAc,CAAU;IAExC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkB;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IAEvC;;;;;;;;;;;;OAYG;IACG,KAAK,CACT,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,mBAAmB,CAAC;IA8B/B;;;;;;;;OAQG;YACW,iBAAiB;IAc/B;;;;;;;;OAQG;YACW,iBAAiB;IA4B/B;;;;;;OAMG;YACW,gBAAgB;IAsB9B;;;;;;OAMG;YACW,kBAAkB;IA8ChC;;;;;;OAMG;YACW,iBAAiB;IAW/B;;;;;;OAMG;YACW,uBAAuB;IAWrC;;;;;;OAMG;YACW,gBAAgB;IAW9B;;;;;;;;;OASG;YACW,qBAAqB;IAwCnC;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAa3B;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IAWtB;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAmB1B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAoBrB;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAsB1B;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;CA2B1B"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import * as fse from "fs-extra";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { PROJECT_TYPE_HIERARCHY } from "../core/config.js";
|
|
4
|
+
import { ensureParentDir } from "../utils/file-operations.js";
|
|
5
|
+
import { readJson, writeJson, deepMerge, readJsonOrNull, } from "../utils/json-utils.js";
|
|
6
|
+
import { JsonMergeError } from "../errors/index.js";
|
|
7
|
+
/**
|
|
8
|
+
* @file package-lisa.ts
|
|
9
|
+
* @description Package.lisa.json strategy for governance-driven package.json management
|
|
10
|
+
*
|
|
11
|
+
* Implements a two-file approach to package.json governance:
|
|
12
|
+
* - Source: package.lisa.json files in type directories (all/, typescript/, expo/, etc.)
|
|
13
|
+
* - Destination: project's package.json
|
|
14
|
+
*
|
|
15
|
+
* Behavior is defined in package.lisa.json:
|
|
16
|
+
* - force: Lisa's values completely replace project's values
|
|
17
|
+
* - defaults: Project's values preserved; Lisa's used only if missing
|
|
18
|
+
* - merge: Arrays concatenated and deduplicated
|
|
19
|
+
*
|
|
20
|
+
* Inheritance chain: all → typescript → specific types (expo, nestjs, cdk, npm-package)
|
|
21
|
+
* Child types override parent values in each section.
|
|
22
|
+
* @module strategies
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Package.lisa.json strategy: Manage package.json via separate template files
|
|
26
|
+
* - Loads templates from all applicable types in inheritance chain
|
|
27
|
+
* - Merges templates (child overrides parent)
|
|
28
|
+
* - Applies force/defaults/merge logic to project's package.json
|
|
29
|
+
* - Keeps project's package.json 100% clean (no Lisa artifacts)
|
|
30
|
+
*/
|
|
31
|
+
export class PackageLisaStrategy {
|
|
32
|
+
name = "package-lisa";
|
|
33
|
+
PACKAGE_JSON = "package.json";
|
|
34
|
+
TSCONFIG_JSON = "tsconfig.json";
|
|
35
|
+
APP_JSON = "app.json";
|
|
36
|
+
EAS_JSON = "eas.json";
|
|
37
|
+
NEST_CLI_JSON = "nest-cli.json";
|
|
38
|
+
CDK_JSON = "cdk.json";
|
|
39
|
+
/**
|
|
40
|
+
* Apply package-lisa strategy: Load templates from inheritance chain, apply to package.json
|
|
41
|
+
* @remarks
|
|
42
|
+
* This strategy is unique because:
|
|
43
|
+
* 1. It loads multiple source files from type hierarchy, not just one
|
|
44
|
+
* 2. It applies structured merge logic (force/defaults/merge) instead of simple JSON merge
|
|
45
|
+
* 3. It never applies changes if source file doesn't exist in ANY type directory
|
|
46
|
+
* @param sourcePath - Path to source package.lisa.json (only used for detecting when to apply)
|
|
47
|
+
* @param destPath - Destination package.json path
|
|
48
|
+
* @param relativePath - Relative path for recording ("package.json")
|
|
49
|
+
* @param context - Strategy context with config and callbacks
|
|
50
|
+
* @returns Result with action "copied", "merged", or "skipped"
|
|
51
|
+
*/
|
|
52
|
+
async apply(sourcePath, destPath, relativePath, context) {
|
|
53
|
+
// Check if any package.lisa.json exists in the Lisa directory
|
|
54
|
+
const packageLisaExists = await fse.pathExists(sourcePath);
|
|
55
|
+
if (!packageLisaExists) {
|
|
56
|
+
// No package.lisa.json found; skip this strategy
|
|
57
|
+
return { relativePath, strategy: this.name, action: "skipped" };
|
|
58
|
+
}
|
|
59
|
+
const destExists = await fse.pathExists(destPath);
|
|
60
|
+
try {
|
|
61
|
+
// Load templates and apply regardless of whether destination exists
|
|
62
|
+
const merged = await this.mergePackageJson(destPath, context);
|
|
63
|
+
if (!destExists) {
|
|
64
|
+
return this.createDestination(destPath, merged, relativePath, context);
|
|
65
|
+
}
|
|
66
|
+
return this.updateDestination(destPath, merged, relativePath, context);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error instanceof JsonMergeError) {
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
throw new JsonMergeError(relativePath, `Failed to apply package-lisa strategy: ${error instanceof Error ? error.message : String(error)}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create destination file when it doesn't exist
|
|
77
|
+
* @param destPath - Path to destination package.json
|
|
78
|
+
* @param merged - Merged package.json object
|
|
79
|
+
* @param relativePath - Relative path for recording
|
|
80
|
+
* @param context - Strategy context with config and callbacks
|
|
81
|
+
* @returns Result with action "copied"
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
async createDestination(destPath, merged, relativePath, context) {
|
|
85
|
+
if (!context.config.dryRun) {
|
|
86
|
+
await ensureParentDir(destPath);
|
|
87
|
+
await writeJson(destPath, merged);
|
|
88
|
+
context.recordFile(relativePath, this.name);
|
|
89
|
+
}
|
|
90
|
+
return { relativePath, strategy: this.name, action: "copied" };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Update destination file when it exists
|
|
94
|
+
* @param destPath - Path to destination package.json
|
|
95
|
+
* @param merged - Merged package.json object
|
|
96
|
+
* @param relativePath - Relative path for recording
|
|
97
|
+
* @param context - Strategy context with config and callbacks
|
|
98
|
+
* @returns Result with action "merged" or "skipped"
|
|
99
|
+
* @private
|
|
100
|
+
*/
|
|
101
|
+
async updateDestination(destPath, merged, relativePath, context) {
|
|
102
|
+
const originalJson = await readJson(destPath);
|
|
103
|
+
// Normalize for comparison
|
|
104
|
+
const normalizedDest = JSON.stringify(originalJson, null, 2);
|
|
105
|
+
const normalizedMerged = JSON.stringify(merged, null, 2);
|
|
106
|
+
if (normalizedDest === normalizedMerged) {
|
|
107
|
+
if (!context.config.dryRun) {
|
|
108
|
+
context.recordFile(relativePath, this.name);
|
|
109
|
+
}
|
|
110
|
+
return { relativePath, strategy: this.name, action: "skipped" };
|
|
111
|
+
}
|
|
112
|
+
if (!context.config.dryRun) {
|
|
113
|
+
await context.backupFile(destPath);
|
|
114
|
+
await writeJson(destPath, merged);
|
|
115
|
+
context.recordFile(relativePath, this.name);
|
|
116
|
+
}
|
|
117
|
+
return { relativePath, strategy: this.name, action: "merged" };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Merge package.json using force/defaults/merge logic from package.lisa.json templates
|
|
121
|
+
* @param packageJsonPath - Absolute path to destination package.json
|
|
122
|
+
* @param context - Strategy context with Lisa config
|
|
123
|
+
* @returns Merged package.json object
|
|
124
|
+
* @private
|
|
125
|
+
*/
|
|
126
|
+
async mergePackageJson(packageJsonPath, context) {
|
|
127
|
+
// Try to read existing package.json, or start with empty object
|
|
128
|
+
const projectJson = (await readJsonOrNull(packageJsonPath)) || {};
|
|
129
|
+
// Extract the Lisa directory from config
|
|
130
|
+
const lisaDir = context.config.lisaDir;
|
|
131
|
+
const projectDir = path.dirname(packageJsonPath);
|
|
132
|
+
// Get detected project types by analyzing the project structure
|
|
133
|
+
const detectedTypes = await this.detectProjectTypes(projectDir);
|
|
134
|
+
// Load and merge all package.lisa.json templates from type hierarchy
|
|
135
|
+
const merged = await this.loadAndMergeTemplates(lisaDir, detectedTypes);
|
|
136
|
+
// Apply force/defaults/merge logic to project's package.json
|
|
137
|
+
return this.applyTemplate(projectJson, merged);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Detect which project types apply to this project
|
|
141
|
+
* (TypeScript, Expo, NestJS, CDK, npm-package)
|
|
142
|
+
* @param projectDir - Root directory of the project
|
|
143
|
+
* @returns Array of detected project types
|
|
144
|
+
* @private
|
|
145
|
+
*/
|
|
146
|
+
async detectProjectTypes(projectDir) {
|
|
147
|
+
const types = [];
|
|
148
|
+
// TypeScript detection
|
|
149
|
+
const hasTypeScript = (await fse.pathExists(path.join(projectDir, this.TSCONFIG_JSON))) ||
|
|
150
|
+
(await this.packageJsonHasKey(projectDir, "typescript"));
|
|
151
|
+
if (hasTypeScript)
|
|
152
|
+
types.push("typescript");
|
|
153
|
+
// Expo detection
|
|
154
|
+
const hasExpo = (await fse.pathExists(path.join(projectDir, this.APP_JSON))) ||
|
|
155
|
+
(await fse.pathExists(path.join(projectDir, this.EAS_JSON))) ||
|
|
156
|
+
(await this.packageJsonHasKey(projectDir, "expo"));
|
|
157
|
+
if (hasExpo)
|
|
158
|
+
types.push("expo");
|
|
159
|
+
// NestJS detection
|
|
160
|
+
const hasNestJS = (await fse.pathExists(path.join(projectDir, this.NEST_CLI_JSON))) ||
|
|
161
|
+
(await this.packageJsonHasKeyPrefix(projectDir, "@nestjs"));
|
|
162
|
+
if (hasNestJS)
|
|
163
|
+
types.push("nestjs");
|
|
164
|
+
// CDK detection
|
|
165
|
+
const hasCDK = (await fse.pathExists(path.join(projectDir, this.CDK_JSON))) ||
|
|
166
|
+
(await this.packageJsonHasKey(projectDir, "aws-cdk"));
|
|
167
|
+
if (hasCDK)
|
|
168
|
+
types.push("cdk");
|
|
169
|
+
// npm-package detection
|
|
170
|
+
const isPrivate = await this.packageJsonField(projectDir, "private");
|
|
171
|
+
const hasPublishField = (await this.packageJsonField(projectDir, "main")) !== undefined ||
|
|
172
|
+
(await this.packageJsonField(projectDir, "bin")) !== undefined ||
|
|
173
|
+
(await this.packageJsonField(projectDir, "exports")) !== undefined ||
|
|
174
|
+
(await this.packageJsonField(projectDir, "files")) !== undefined;
|
|
175
|
+
if (!isPrivate && hasPublishField) {
|
|
176
|
+
types.push("npm-package");
|
|
177
|
+
}
|
|
178
|
+
return types;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Check if package.json contains a key
|
|
182
|
+
* @param projectDir - The project directory to check
|
|
183
|
+
* @param key - The key to check for in package.json
|
|
184
|
+
* @returns True if the key exists in package.json, false otherwise
|
|
185
|
+
* @private
|
|
186
|
+
*/
|
|
187
|
+
async packageJsonHasKey(projectDir, key) {
|
|
188
|
+
const packageJson = await readJsonOrNull(path.join(projectDir, this.PACKAGE_JSON));
|
|
189
|
+
if (!packageJson)
|
|
190
|
+
return false;
|
|
191
|
+
return key in packageJson;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Check if package.json contains a key that starts with a prefix (for scoped packages)
|
|
195
|
+
* @param projectDir - The project directory to check
|
|
196
|
+
* @param prefix - The prefix to check for (e.g., "@nestjs" or "@aws-sdk")
|
|
197
|
+
* @returns True if any key in package.json starts with the given prefix, false otherwise
|
|
198
|
+
* @private
|
|
199
|
+
*/
|
|
200
|
+
async packageJsonHasKeyPrefix(projectDir, prefix) {
|
|
201
|
+
const packageJson = await readJsonOrNull(path.join(projectDir, this.PACKAGE_JSON));
|
|
202
|
+
if (!packageJson)
|
|
203
|
+
return false;
|
|
204
|
+
return Object.keys(packageJson).some(key => key.startsWith(prefix));
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get a field value from package.json
|
|
208
|
+
* @param projectDir - The project directory containing the package.json
|
|
209
|
+
* @param fieldName - The field name to retrieve from package.json
|
|
210
|
+
* @returns The field value if found, undefined if not found or if package.json doesn't exist
|
|
211
|
+
* @private
|
|
212
|
+
*/
|
|
213
|
+
async packageJsonField(projectDir, fieldName) {
|
|
214
|
+
const packageJson = await readJsonOrNull(path.join(projectDir, this.PACKAGE_JSON));
|
|
215
|
+
if (!packageJson)
|
|
216
|
+
return undefined;
|
|
217
|
+
return packageJson[fieldName];
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Load and merge all package.lisa.json templates from type hierarchy
|
|
221
|
+
* @remarks
|
|
222
|
+
* Inheritance chain: all → typescript → specific types (expo, nestjs, cdk, npm-package)
|
|
223
|
+
* Child types override parent types in force, defaults, and merge sections.
|
|
224
|
+
* @param lisaDir - Root Lisa directory path
|
|
225
|
+
* @param detectedTypes - Project types to load templates for
|
|
226
|
+
* @returns Merged template with force, defaults, merge sections
|
|
227
|
+
* @private
|
|
228
|
+
*/
|
|
229
|
+
async loadAndMergeTemplates(lisaDir, detectedTypes) {
|
|
230
|
+
const initial = {
|
|
231
|
+
force: {},
|
|
232
|
+
defaults: {},
|
|
233
|
+
merge: {},
|
|
234
|
+
};
|
|
235
|
+
// Expand types to include parents (e.g., expo includes typescript)
|
|
236
|
+
const allTypes = this.expandTypeHierarchy(detectedTypes);
|
|
237
|
+
// Process types in order: all, then typescript, then specific types
|
|
238
|
+
const typesToProcess = ["all", ...allTypes];
|
|
239
|
+
// Load and merge all templates using reduce
|
|
240
|
+
// eslint-disable-next-line functional/no-let -- Reassignment needed for async loop
|
|
241
|
+
let accumulator = initial;
|
|
242
|
+
for (const type of typesToProcess) {
|
|
243
|
+
const templatePath = path.join(lisaDir, type, "tagged-merge", "package.lisa.json");
|
|
244
|
+
const template = await readJsonOrNull(templatePath);
|
|
245
|
+
if (!template) {
|
|
246
|
+
// Template doesn't exist for this type; skip
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
// Merge template into accumulated template (child overrides parent)
|
|
250
|
+
accumulator = this.mergeTemplates(accumulator, template);
|
|
251
|
+
}
|
|
252
|
+
return accumulator;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Expand project types to include parent types
|
|
256
|
+
* @remarks
|
|
257
|
+
* Type hierarchy: expo/nestjs/cdk/npm-package inherit from typescript
|
|
258
|
+
* This expands a list to include parents.
|
|
259
|
+
* Example: [expo] → [typescript, expo]
|
|
260
|
+
* @param types - Project types detected
|
|
261
|
+
* @returns Expanded types including parents
|
|
262
|
+
* @private
|
|
263
|
+
*/
|
|
264
|
+
expandTypeHierarchy(types) {
|
|
265
|
+
const allTypes = new Set(types);
|
|
266
|
+
for (const type of types) {
|
|
267
|
+
const parent = PROJECT_TYPE_HIERARCHY[type];
|
|
268
|
+
if (parent) {
|
|
269
|
+
allTypes.add(parent);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return Array.from(allTypes);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Merge two template objects
|
|
276
|
+
* Child template (override) values win in force and defaults.
|
|
277
|
+
* Merge arrays are concatenated without deduplication at merge time.
|
|
278
|
+
* @param parent - Parent template (e.g., "all" or "typescript")
|
|
279
|
+
* @param child - Child template (e.g., "expo") that overrides parent
|
|
280
|
+
* @returns Merged template
|
|
281
|
+
* @private
|
|
282
|
+
*/
|
|
283
|
+
mergeTemplates(parent, child) {
|
|
284
|
+
return {
|
|
285
|
+
force: deepMerge(parent.force, child.force || {}),
|
|
286
|
+
defaults: deepMerge(parent.defaults, child.defaults || {}),
|
|
287
|
+
merge: this.mergeMergeSections(parent.merge, child.merge || {}),
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Merge two merge-section objects
|
|
292
|
+
* Arrays are concatenated (deduplication happens later when applied to package.json)
|
|
293
|
+
* @param parent - Parent merge sections
|
|
294
|
+
* @param child - Child merge sections
|
|
295
|
+
* @returns Merged sections
|
|
296
|
+
* @private
|
|
297
|
+
*/
|
|
298
|
+
mergeMergeSections(parent, child) {
|
|
299
|
+
const result = { ...parent };
|
|
300
|
+
for (const [key, value] of Object.entries(child)) {
|
|
301
|
+
if (key in result) {
|
|
302
|
+
// Concatenate arrays
|
|
303
|
+
const existing = result[key];
|
|
304
|
+
result[key] = [...existing, ...value];
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
result[key] = value;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Apply force/defaults/merge logic to project's package.json
|
|
314
|
+
* @remarks
|
|
315
|
+
* Processing order:
|
|
316
|
+
* 1. Apply force: Deep merge with Lisa values winning (entire section replaced)
|
|
317
|
+
* 2. Apply defaults: Deep merge with project values winning (only set if missing)
|
|
318
|
+
* 3. Apply merge: Concatenate arrays and deduplicate
|
|
319
|
+
* @param projectJson - Current project's package.json
|
|
320
|
+
* @param template - Merged package.lisa.json template
|
|
321
|
+
* @returns Modified package.json
|
|
322
|
+
* @private
|
|
323
|
+
*/
|
|
324
|
+
applyTemplate(projectJson, template) {
|
|
325
|
+
// Phase 1: Apply force (Lisa's values completely replace project's)
|
|
326
|
+
const afterForce = deepMerge(projectJson, template.force);
|
|
327
|
+
// Phase 2: Apply defaults (project's values preserved, Lisa provides fallback)
|
|
328
|
+
const afterDefaults = deepMerge(template.defaults, afterForce);
|
|
329
|
+
// Phase 3: Apply merge (concatenate and deduplicate arrays)
|
|
330
|
+
return this.applyMergeSections(afterDefaults, template.merge);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Apply merge-section arrays to package.json
|
|
334
|
+
* Concatenates Lisa's items and project's items, deduplicated by JSON.stringify equality.
|
|
335
|
+
* @param packageJson - Current package.json after force/defaults applied
|
|
336
|
+
* @param mergeSections - Merge sections from template
|
|
337
|
+
* @returns Package.json with merge sections applied
|
|
338
|
+
* @private
|
|
339
|
+
*/
|
|
340
|
+
applyMergeSections(packageJson, mergeSections) {
|
|
341
|
+
const result = { ...packageJson };
|
|
342
|
+
for (const [key, lisaItems] of Object.entries(mergeSections)) {
|
|
343
|
+
const projectItems = result[key] || [];
|
|
344
|
+
if (!Array.isArray(projectItems)) {
|
|
345
|
+
// If the field exists but isn't an array, replace it with Lisa's items
|
|
346
|
+
result[key] = lisaItems;
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
// Concatenate and deduplicate: Lisa items first, then project's unique items
|
|
350
|
+
result[key] = this.deduplicateArrays(lisaItems, projectItems);
|
|
351
|
+
}
|
|
352
|
+
return result;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Concatenate two arrays and remove duplicates
|
|
356
|
+
* Uses JSON.stringify for value equality comparison.
|
|
357
|
+
* Lisa items come first, then project's unique items.
|
|
358
|
+
* @param lisaItems - Lisa's items (come first)
|
|
359
|
+
* @param projectItems - Project's items (added if not already present)
|
|
360
|
+
* @returns Deduplicated array
|
|
361
|
+
* @private
|
|
362
|
+
*/
|
|
363
|
+
deduplicateArrays(lisaItems, projectItems) {
|
|
364
|
+
const seen = new Set();
|
|
365
|
+
const result = [];
|
|
366
|
+
// Add Lisa items first
|
|
367
|
+
for (const item of lisaItems) {
|
|
368
|
+
const key = JSON.stringify(item);
|
|
369
|
+
if (!seen.has(key)) {
|
|
370
|
+
seen.add(key);
|
|
371
|
+
result.push(item);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
// Add project's unique items
|
|
375
|
+
for (const item of projectItems) {
|
|
376
|
+
const key = JSON.stringify(item);
|
|
377
|
+
if (!seen.has(key)) {
|
|
378
|
+
seen.add(key);
|
|
379
|
+
result.push(item);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return result;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=package-lisa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-lisa.js","sourceRoot":"","sources":["../../src/strategies/package-lisa.ts"],"names":[],"mappings":"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"}
|