@react-spa-scaffold/mcp 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.ts +35 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +35 -0
- package/dist/constants.js.map +1 -0
- package/dist/features/definitions/theming.d.ts.map +1 -1
- package/dist/features/definitions/theming.js +2 -1
- package/dist/features/definitions/theming.js.map +1 -1
- package/dist/features/types.d.ts +14 -19
- package/dist/features/types.d.ts.map +1 -1
- package/dist/features/types.js +4 -21
- package/dist/features/types.js.map +1 -1
- package/dist/features/types.test.d.ts +5 -0
- package/dist/features/types.test.d.ts.map +1 -0
- package/dist/features/types.test.js +32 -0
- package/dist/features/types.test.js.map +1 -0
- package/dist/resources/docs.d.ts +2 -8
- package/dist/resources/docs.d.ts.map +1 -1
- package/dist/resources/docs.js +27 -49
- package/dist/resources/docs.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/get-example.d.ts +4 -15
- package/dist/tools/get-example.d.ts.map +1 -1
- package/dist/tools/get-example.js +3 -11
- package/dist/tools/get-example.js.map +1 -1
- package/dist/tools/get-features.d.ts +15 -9
- package/dist/tools/get-features.d.ts.map +1 -1
- package/dist/tools/get-features.js +12 -0
- package/dist/tools/get-features.js.map +1 -1
- package/dist/tools/get-file.d.ts +23 -0
- package/dist/tools/get-file.d.ts.map +1 -0
- package/dist/tools/get-file.js +53 -0
- package/dist/tools/get-file.js.map +1 -0
- package/dist/tools/get-file.test.d.ts +5 -0
- package/dist/tools/get-file.test.d.ts.map +1 -0
- package/dist/tools/get-file.test.js +63 -0
- package/dist/tools/get-file.test.js.map +1 -0
- package/dist/tools/get-scaffold.d.ts +8 -29
- package/dist/tools/get-scaffold.d.ts.map +1 -1
- package/dist/tools/get-scaffold.js +18 -24
- package/dist/tools/get-scaffold.js.map +1 -1
- package/dist/tools/get-scaffold.test.js +19 -16
- package/dist/tools/get-scaffold.test.js.map +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/registry.d.ts +4 -0
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +33 -15
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/types.d.ts +24 -6
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js +3 -0
- package/dist/tools/types.js.map +1 -1
- package/dist/utils/cache.d.ts +9 -5
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/cache.js +21 -5
- package/dist/utils/cache.js.map +1 -1
- package/dist/utils/docs.d.ts +1 -3
- package/dist/utils/docs.d.ts.map +1 -1
- package/dist/utils/docs.js +3 -8
- package/dist/utils/docs.js.map +1 -1
- package/dist/utils/examples/index.d.ts +1 -1
- package/dist/utils/examples/index.d.ts.map +1 -1
- package/dist/utils/examples/index.js +6 -10
- package/dist/utils/examples/index.js.map +1 -1
- package/dist/utils/examples/patterns.test.d.ts +6 -0
- package/dist/utils/examples/patterns.test.d.ts.map +1 -0
- package/dist/utils/examples/patterns.test.js +75 -0
- package/dist/utils/examples/patterns.test.js.map +1 -0
- package/dist/utils/paths.d.ts +9 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +19 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/paths.test.js +22 -1
- package/dist/utils/paths.test.js.map +1 -1
- package/dist/utils/scaffold/claude-md/index.d.ts +7 -0
- package/dist/utils/scaffold/claude-md/index.d.ts.map +1 -0
- package/dist/utils/scaffold/claude-md/index.js +23 -0
- package/dist/utils/scaffold/claude-md/index.js.map +1 -0
- package/dist/utils/scaffold/claude-md/sections.d.ts +16 -0
- package/dist/utils/scaffold/claude-md/sections.d.ts.map +1 -0
- package/dist/utils/scaffold/claude-md/sections.js +269 -0
- package/dist/utils/scaffold/claude-md/sections.js.map +1 -0
- package/dist/utils/scaffold/commands.d.ts +2 -6
- package/dist/utils/scaffold/commands.d.ts.map +1 -1
- package/dist/utils/scaffold/commands.js +9 -12
- package/dist/utils/scaffold/commands.js.map +1 -1
- package/dist/utils/scaffold/compute.d.ts +5 -8
- package/dist/utils/scaffold/compute.d.ts.map +1 -1
- package/dist/utils/scaffold/compute.js +26 -41
- package/dist/utils/scaffold/compute.js.map +1 -1
- package/dist/utils/scaffold/dependencies.d.ts +10 -17
- package/dist/utils/scaffold/dependencies.d.ts.map +1 -1
- package/dist/utils/scaffold/dependencies.js +28 -34
- package/dist/utils/scaffold/dependencies.js.map +1 -1
- package/dist/utils/scaffold/generators.d.ts +3 -11
- package/dist/utils/scaffold/generators.d.ts.map +1 -1
- package/dist/utils/scaffold/generators.js +20 -288
- package/dist/utils/scaffold/generators.js.map +1 -1
- package/dist/utils/scaffold/index.d.ts +2 -3
- package/dist/utils/scaffold/index.d.ts.map +1 -1
- package/dist/utils/scaffold/index.js +1 -3
- package/dist/utils/scaffold/index.js.map +1 -1
- package/package.json +2 -2
package/dist/utils/cache.d.ts
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* In-memory cache utilities for MCP server.
|
|
3
3
|
*/
|
|
4
|
-
/** Creates a typed cache with getOrSet
|
|
4
|
+
/** Creates a typed key-value cache with sync and async getOrSet patterns. */
|
|
5
5
|
export declare function createCache<T>(): {
|
|
6
6
|
get: (key: string) => T | undefined;
|
|
7
7
|
set: (key: string, value: T) => void;
|
|
8
8
|
has: (key: string) => boolean;
|
|
9
9
|
clear: () => void;
|
|
10
|
-
/** Gets cached value or computes and caches it. */
|
|
10
|
+
/** Gets cached value or computes and caches it (sync). */
|
|
11
|
+
getOrSetSync(key: string, factory: () => T): T;
|
|
12
|
+
/** Gets cached value or computes and caches it (async). */
|
|
11
13
|
getOrSet(key: string, factory: () => Promise<T>): Promise<T>;
|
|
12
14
|
};
|
|
13
|
-
/** Creates a
|
|
15
|
+
/** Creates a singleton cache (single value, no key). */
|
|
14
16
|
export declare function createSingletonCache<T>(): {
|
|
15
17
|
get: () => T | null;
|
|
16
18
|
set: (value: T) => void;
|
|
17
19
|
clear: () => void;
|
|
18
|
-
/** Gets cached value or computes
|
|
20
|
+
/** Gets cached value or computes (sync). */
|
|
21
|
+
getOrSetSync(factory: () => T): T;
|
|
22
|
+
/** Gets cached value or computes (async). */
|
|
19
23
|
getOrSet(factory: () => Promise<T>): Promise<T>;
|
|
20
24
|
};
|
|
21
25
|
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,CAAC;eAId,MAAM,KAAG,CAAC,GAAG,SAAS;eACtB,MAAM,SAAS,CAAC,KAAG,IAAI;eAGvB,MAAM,KAAG,OAAO;iBAChB,IAAI;IAEf,0DAA0D;sBACxC,MAAM,WAAW,MAAM,CAAC,GAAG,CAAC;IAQ9C,2DAA2D;kBACvC,MAAM,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;EAQrE;AAED,wDAAwD;AACxD,wBAAgB,oBAAoB,CAAC,CAAC;eAIzB,CAAC,GAAG,IAAI;iBACJ,CAAC,KAAG,IAAI;iBAGV,IAAI;IAIf,4CAA4C;0BACtB,MAAM,CAAC,GAAG,CAAC;IAMjC,6CAA6C;sBACrB,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;EAMxD"}
|
package/dist/utils/cache.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* In-memory cache utilities for MCP server.
|
|
3
3
|
*/
|
|
4
|
-
/** Creates a typed cache with getOrSet
|
|
4
|
+
/** Creates a typed key-value cache with sync and async getOrSet patterns. */
|
|
5
5
|
export function createCache() {
|
|
6
6
|
const cache = new Map();
|
|
7
7
|
return {
|
|
@@ -11,7 +11,16 @@ export function createCache() {
|
|
|
11
11
|
},
|
|
12
12
|
has: (key) => cache.has(key),
|
|
13
13
|
clear: () => cache.clear(),
|
|
14
|
-
/** Gets cached value or computes and caches it. */
|
|
14
|
+
/** Gets cached value or computes and caches it (sync). */
|
|
15
|
+
getOrSetSync(key, factory) {
|
|
16
|
+
const existing = cache.get(key);
|
|
17
|
+
if (existing !== undefined)
|
|
18
|
+
return existing;
|
|
19
|
+
const value = factory();
|
|
20
|
+
cache.set(key, value);
|
|
21
|
+
return value;
|
|
22
|
+
},
|
|
23
|
+
/** Gets cached value or computes and caches it (async). */
|
|
15
24
|
async getOrSet(key, factory) {
|
|
16
25
|
const existing = cache.get(key);
|
|
17
26
|
if (existing !== undefined)
|
|
@@ -22,7 +31,7 @@ export function createCache() {
|
|
|
22
31
|
},
|
|
23
32
|
};
|
|
24
33
|
}
|
|
25
|
-
/** Creates a
|
|
34
|
+
/** Creates a singleton cache (single value, no key). */
|
|
26
35
|
export function createSingletonCache() {
|
|
27
36
|
let cached = null;
|
|
28
37
|
return {
|
|
@@ -33,7 +42,14 @@ export function createSingletonCache() {
|
|
|
33
42
|
clear: () => {
|
|
34
43
|
cached = null;
|
|
35
44
|
},
|
|
36
|
-
/** Gets cached value or computes
|
|
45
|
+
/** Gets cached value or computes (sync). */
|
|
46
|
+
getOrSetSync(factory) {
|
|
47
|
+
if (cached !== null)
|
|
48
|
+
return cached;
|
|
49
|
+
cached = factory();
|
|
50
|
+
return cached;
|
|
51
|
+
},
|
|
52
|
+
/** Gets cached value or computes (async). */
|
|
37
53
|
async getOrSet(factory) {
|
|
38
54
|
if (cached !== null)
|
|
39
55
|
return cached;
|
package/dist/utils/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6EAA6E;AAC7E,MAAM,UAAU,WAAW;IACzB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAa,CAAC;IAEnC,OAAO;QACL,GAAG,EAAE,CAAC,GAAW,EAAiB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;QACnD,GAAG,EAAE,CAAC,GAAW,EAAE,KAAQ,EAAQ,EAAE;YACnC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,GAAG,EAAE,CAAC,GAAW,EAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;QAC7C,KAAK,EAAE,GAAS,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE;QAEhC,0DAA0D;QAC1D,YAAY,CAAC,GAAW,EAAE,OAAgB;YACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,QAAQ,KAAK,SAAS;gBAAE,OAAO,QAAQ,CAAC;YAC5C,MAAM,KAAK,GAAG,OAAO,EAAE,CAAC;YACxB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,2DAA2D;QAC3D,KAAK,CAAC,QAAQ,CAAC,GAAW,EAAE,OAAyB;YACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,QAAQ,KAAK,SAAS;gBAAE,OAAO,QAAQ,CAAC;YAC5C,MAAM,KAAK,GAAG,MAAM,OAAO,EAAE,CAAC;YAC9B,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,oBAAoB;IAClC,IAAI,MAAM,GAAa,IAAI,CAAC;IAE5B,OAAO;QACL,GAAG,EAAE,GAAa,EAAE,CAAC,MAAM;QAC3B,GAAG,EAAE,CAAC,KAAQ,EAAQ,EAAE;YACtB,MAAM,GAAG,KAAK,CAAC;QACjB,CAAC;QACD,KAAK,EAAE,GAAS,EAAE;YAChB,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;QAED,4CAA4C;QAC5C,YAAY,CAAC,OAAgB;YAC3B,IAAI,MAAM,KAAK,IAAI;gBAAE,OAAO,MAAM,CAAC;YACnC,MAAM,GAAG,OAAO,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,6CAA6C;QAC7C,KAAK,CAAC,QAAQ,CAAC,OAAyB;YACtC,IAAI,MAAM,KAAK,IAAI;gBAAE,OAAO,MAAM,CAAC;YACnC,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/utils/docs.d.ts
CHANGED
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
* Determine which docs to include based on selected features
|
|
8
8
|
*/
|
|
9
9
|
export declare function computeDocsForFeatures(featureIds: readonly string[]): string[];
|
|
10
|
-
/**
|
|
11
|
-
* Read all docs for scaffolding based on selected features
|
|
12
|
-
*/
|
|
10
|
+
/** Read all docs for scaffolding based on selected features (parallel). */
|
|
13
11
|
export declare function computeDocsContent(featureIds: readonly string[]): Promise<Record<string, string>>;
|
|
14
12
|
//# sourceMappingURL=docs.d.ts.map
|
package/dist/utils/docs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/utils/docs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA2BH;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAU9E;AAeD
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/utils/docs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA2BH;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAU9E;AAeD,2EAA2E;AAC3E,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAIvG"}
|
package/dist/utils/docs.js
CHANGED
|
@@ -50,15 +50,10 @@ async function readDoc(docPath) {
|
|
|
50
50
|
return `<!-- File not found: ${docPath} -->\n<!-- Run MCP server from within react-spa-scaffold repository -->`;
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Read all docs for scaffolding based on selected features
|
|
55
|
-
*/
|
|
53
|
+
/** Read all docs for scaffolding based on selected features (parallel). */
|
|
56
54
|
export async function computeDocsContent(featureIds) {
|
|
57
55
|
const docPaths = computeDocsForFeatures(featureIds);
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
docs[docPath] = await readDoc(docPath);
|
|
61
|
-
}
|
|
62
|
-
return docs;
|
|
56
|
+
const contents = await Promise.all(docPaths.map(readDoc));
|
|
57
|
+
return Object.fromEntries(docPaths.map((path, i) => [path, contents[i]]));
|
|
63
58
|
}
|
|
64
59
|
//# sourceMappingURL=docs.js.map
|
package/dist/utils/docs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/utils/docs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,WAAW,GAAoD;IACnE,8BAA8B;IAC9B,sBAAsB,EAAE,EAAE;IAC1B,0BAA0B,EAAE,EAAE;IAC9B,8BAA8B,EAAE,EAAE;IAClC,uBAAuB,EAAE,EAAE;IAE3B,mBAAmB;IACnB,iBAAiB,EAAE,EAAE,gBAAgB,EAAE,CAAC,SAAS,CAAC,EAAE;IACpD,qBAAqB,EAAE,EAAE,gBAAgB,EAAE,CAAC,SAAS,CAAC,EAAE;IACxD,8BAA8B,EAAE,EAAE,gBAAgB,EAAE,CAAC,MAAM,CAAC,EAAE;CAC/D,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAA6B;IAClE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAEvC,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;SAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE;QACrB,IAAI,CAAC,MAAM,CAAC,gBAAgB;YAAE,OAAO,IAAI,CAAC,CAAC,YAAY;QACvD,OAAO,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC;SACrB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,OAAO,CAAC,OAAe;IACpC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE9C,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,wBAAwB,OAAO,yEAAyE,CAAC;IAClH,CAAC;AACH,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/utils/docs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,WAAW,GAAoD;IACnE,8BAA8B;IAC9B,sBAAsB,EAAE,EAAE;IAC1B,0BAA0B,EAAE,EAAE;IAC9B,8BAA8B,EAAE,EAAE;IAClC,uBAAuB,EAAE,EAAE;IAE3B,mBAAmB;IACnB,iBAAiB,EAAE,EAAE,gBAAgB,EAAE,CAAC,SAAS,CAAC,EAAE;IACpD,qBAAqB,EAAE,EAAE,gBAAgB,EAAE,CAAC,SAAS,CAAC,EAAE;IACxD,8BAA8B,EAAE,EAAE,gBAAgB,EAAE,CAAC,MAAM,CAAC,EAAE;CAC/D,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAA6B;IAClE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAEvC,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;SAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE;QACrB,IAAI,CAAC,MAAM,CAAC,gBAAgB;YAAE,OAAO,IAAI,CAAC,CAAC,YAAY;QACvD,OAAO,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC;SACrB,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,OAAO,CAAC,OAAe;IACpC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE9C,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,wBAAwB,OAAO,yEAAyE,CAAC;IAClH,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAA6B;IACpE,MAAM,QAAQ,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1D,OAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -7,6 +7,6 @@ export type { CodeExample } from './types.js';
|
|
|
7
7
|
export declare function getAvailablePatterns(): string[];
|
|
8
8
|
/** Get code example for a pattern. */
|
|
9
9
|
export declare function getCodeExample(pattern: string): Promise<CodeExample | null>;
|
|
10
|
-
/** Get all examples for a list of patterns. */
|
|
10
|
+
/** Get all examples for a list of patterns (parallel). */
|
|
11
11
|
export declare function getFeatureExamples(patterns: string[]): Promise<CodeExample[]>;
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/examples/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,YAAY,CAAC;AAY1D,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/examples/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,YAAY,CAAC;AAY1D,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAkB9C,uCAAuC;AACvC,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C;AAED,sCAAsC;AACtC,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAwBjF;AAED,0DAA0D;AAC1D,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAGnF"}
|
|
@@ -13,7 +13,7 @@ import { apiPatterns } from './api-patterns.js';
|
|
|
13
13
|
import { testPatterns } from './test-patterns.js';
|
|
14
14
|
import { i18nPatterns } from './i18n-patterns.js';
|
|
15
15
|
import { utilityPatterns } from './utility-patterns.js';
|
|
16
|
-
/** All pattern definitions merged. */
|
|
16
|
+
/** All pattern definitions merged at startup. */
|
|
17
17
|
const PATTERN_MAP = {
|
|
18
18
|
...componentPatterns,
|
|
19
19
|
...hookPatterns,
|
|
@@ -26,9 +26,10 @@ const PATTERN_MAP = {
|
|
|
26
26
|
...i18nPatterns,
|
|
27
27
|
...utilityPatterns,
|
|
28
28
|
};
|
|
29
|
+
const PATTERN_NAMES = Object.keys(PATTERN_MAP).sort();
|
|
29
30
|
/** Get all available pattern names. */
|
|
30
31
|
export function getAvailablePatterns() {
|
|
31
|
-
return
|
|
32
|
+
return PATTERN_NAMES;
|
|
32
33
|
}
|
|
33
34
|
/** Get code example for a pattern. */
|
|
34
35
|
export async function getCodeExample(pattern) {
|
|
@@ -56,14 +57,9 @@ export async function getCodeExample(pattern) {
|
|
|
56
57
|
};
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
|
-
/** Get all examples for a list of patterns. */
|
|
60
|
+
/** Get all examples for a list of patterns (parallel). */
|
|
60
61
|
export async function getFeatureExamples(patterns) {
|
|
61
|
-
const examples =
|
|
62
|
-
|
|
63
|
-
const example = await getCodeExample(pattern);
|
|
64
|
-
if (example)
|
|
65
|
-
examples.push(example);
|
|
66
|
-
}
|
|
67
|
-
return examples;
|
|
62
|
+
const examples = await Promise.all(patterns.map(getCodeExample));
|
|
63
|
+
return examples.filter((e) => e !== null);
|
|
68
64
|
}
|
|
69
65
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/examples/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIxD,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/examples/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIxD,iDAAiD;AACjD,MAAM,WAAW,GAAe;IAC9B,GAAG,iBAAiB;IACpB,GAAG,YAAY;IACf,GAAG,cAAc;IACjB,GAAG,aAAa;IAChB,GAAG,YAAY;IACf,GAAG,eAAe;IAClB,GAAG,WAAW;IACd,GAAG,YAAY;IACf,GAAG,YAAY;IACf,GAAG,eAAe;CACnB,CAAC;AAEF,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC;AAEtD,uCAAuC;AACvC,MAAM,UAAU,oBAAoB;IAClC,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,sCAAsC;AACtC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAe;IAClD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO;YACL,OAAO;YACP,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ,EAAE,OAAO,CAAC,IAAI;YACtB,IAAI;YACJ,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,OAAO;YACP,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ,EAAE,OAAO,CAAC,IAAI;YACtB,IAAI,EAAE,sBAAsB,OAAO,CAAC,IAAI,+DAA+D;YACvG,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC;IACJ,CAAC;AACH,CAAC;AAED,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,QAAkB;IACzD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;IACjE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAoB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.test.d.ts","sourceRoot":"","sources":["../../../src/utils/examples/patterns.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern definition validation tests.
|
|
3
|
+
* Ensures all pattern file paths exist and definitions are complete.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import { describe, it, expect } from 'vitest';
|
|
7
|
+
import { resolveTemplatePath } from '../paths.js';
|
|
8
|
+
import { getAvailablePatterns, getCodeExample } from './index.js';
|
|
9
|
+
// Import all pattern maps to test
|
|
10
|
+
import { componentPatterns } from './component-patterns.js';
|
|
11
|
+
import { hookPatterns } from './hook-patterns.js';
|
|
12
|
+
import { mobilePatterns } from './mobile-patterns.js';
|
|
13
|
+
import { storePatterns } from './store-patterns.js';
|
|
14
|
+
import { pagePatterns } from './page-patterns.js';
|
|
15
|
+
import { contextPatterns } from './context-patterns.js';
|
|
16
|
+
import { apiPatterns } from './api-patterns.js';
|
|
17
|
+
import { testPatterns } from './test-patterns.js';
|
|
18
|
+
import { i18nPatterns } from './i18n-patterns.js';
|
|
19
|
+
import { utilityPatterns } from './utility-patterns.js';
|
|
20
|
+
const ALL_PATTERNS = {
|
|
21
|
+
...componentPatterns,
|
|
22
|
+
...hookPatterns,
|
|
23
|
+
...mobilePatterns,
|
|
24
|
+
...storePatterns,
|
|
25
|
+
...pagePatterns,
|
|
26
|
+
...contextPatterns,
|
|
27
|
+
...apiPatterns,
|
|
28
|
+
...testPatterns,
|
|
29
|
+
...i18nPatterns,
|
|
30
|
+
...utilityPatterns,
|
|
31
|
+
};
|
|
32
|
+
describe('pattern definitions', () => {
|
|
33
|
+
const patterns = Object.entries(ALL_PATTERNS);
|
|
34
|
+
it.each(patterns)('pattern "%s" points to existing file', (_, def) => {
|
|
35
|
+
const fullPath = resolveTemplatePath(def.file);
|
|
36
|
+
expect(existsSync(fullPath), `File not found: ${def.file}`).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it.each(patterns)('pattern "%s" has description', (_, def) => {
|
|
39
|
+
expect(def.description).toBeTruthy();
|
|
40
|
+
expect(def.description.length).toBeGreaterThan(10);
|
|
41
|
+
});
|
|
42
|
+
it.each(patterns)('pattern "%s" has keyPoints array', (_, def) => {
|
|
43
|
+
expect(Array.isArray(def.keyPoints)).toBe(true);
|
|
44
|
+
expect(def.keyPoints.length).toBeGreaterThan(0);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe('getAvailablePatterns', () => {
|
|
48
|
+
it('returns sorted array of pattern names', () => {
|
|
49
|
+
const patterns = getAvailablePatterns();
|
|
50
|
+
expect(patterns.length).toBeGreaterThan(0);
|
|
51
|
+
expect(patterns).toEqual([...patterns].sort());
|
|
52
|
+
});
|
|
53
|
+
it('includes all pattern categories', () => {
|
|
54
|
+
const patterns = getAvailablePatterns();
|
|
55
|
+
expect(patterns).toContain('component-ui');
|
|
56
|
+
expect(patterns).toContain('hook-state');
|
|
57
|
+
expect(patterns).toContain('zustand-store');
|
|
58
|
+
expect(patterns).toContain('test-component');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('getCodeExample', () => {
|
|
62
|
+
it('returns null for unknown pattern', async () => {
|
|
63
|
+
const result = await getCodeExample('non-existent-pattern');
|
|
64
|
+
expect(result).toBeNull();
|
|
65
|
+
});
|
|
66
|
+
it('returns complete example for valid pattern', async () => {
|
|
67
|
+
const result = await getCodeExample('component-ui');
|
|
68
|
+
expect(result).not.toBeNull();
|
|
69
|
+
expect(result?.pattern).toBe('component-ui');
|
|
70
|
+
expect(result?.code).toBeTruthy();
|
|
71
|
+
expect(result?.description).toBeTruthy();
|
|
72
|
+
expect(result?.keyPoints.length).toBeGreaterThan(0);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=patterns.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patterns.test.js","sourceRoot":"","sources":["../../../src/utils/examples/patterns.test.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/paths.d.ts
CHANGED
|
@@ -7,4 +7,13 @@ export declare const isPublishedMode: boolean;
|
|
|
7
7
|
export declare const CONTENT_ROOT: string;
|
|
8
8
|
/** Resolves path relative to content root, handling dotfile renames in published mode. */
|
|
9
9
|
export declare function resolveTemplatePath(relativePath: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Check if resolved path is within CONTENT_ROOT (prevent path traversal).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* isPathWithinRoot('vite.config.ts') // true
|
|
15
|
+
* isPathWithinRoot('../../../etc/passwd') // false
|
|
16
|
+
* isPathWithinRoot('/etc/passwd') // false
|
|
17
|
+
*/
|
|
18
|
+
export declare function isPathWithinRoot(relativePath: string): boolean;
|
|
10
19
|
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,6DAA6D;AAC7D,eAAO,MAAM,eAAe,SAA4B,CAAC;AAEzD,gDAAgD;AAChD,eAAO,MAAM,YAAY,QAAiD,CAAC;AAO3E,0FAA0F;AAC1F,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAKhE"}
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,6DAA6D;AAC7D,eAAO,MAAM,eAAe,SAA4B,CAAC;AAEzD,gDAAgD;AAChD,eAAO,MAAM,YAAY,QAAiD,CAAC;AAO3E,0FAA0F;AAC1F,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAKhE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAW9D"}
|
package/dist/utils/paths.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Path resolution for MCP server - handles dev vs published mode.
|
|
3
3
|
*/
|
|
4
4
|
import { existsSync } from 'fs';
|
|
5
|
-
import { dirname, join } from 'path';
|
|
5
|
+
import { dirname, isAbsolute, join, normalize } from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
const BUNDLED_PATH = join(__dirname, '..', '..', 'templates');
|
|
@@ -21,4 +21,22 @@ export function resolveTemplatePath(relativePath) {
|
|
|
21
21
|
const resolvedPath = isPublishedMode && RENAMED_DOTFILES[relativePath] ? RENAMED_DOTFILES[relativePath] : relativePath;
|
|
22
22
|
return join(CONTENT_ROOT, resolvedPath);
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if resolved path is within CONTENT_ROOT (prevent path traversal).
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* isPathWithinRoot('vite.config.ts') // true
|
|
29
|
+
* isPathWithinRoot('../../../etc/passwd') // false
|
|
30
|
+
* isPathWithinRoot('/etc/passwd') // false
|
|
31
|
+
*/
|
|
32
|
+
export function isPathWithinRoot(relativePath) {
|
|
33
|
+
// Reject absolute paths - they bypass CONTENT_ROOT
|
|
34
|
+
if (isAbsolute(relativePath)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const fullPath = join(CONTENT_ROOT, relativePath);
|
|
38
|
+
const normalizedPath = normalize(fullPath);
|
|
39
|
+
const normalizedRoot = normalize(CONTENT_ROOT);
|
|
40
|
+
return normalizedPath.startsWith(normalizedRoot + '/') || normalizedPath === normalizedRoot;
|
|
41
|
+
}
|
|
24
42
|
//# sourceMappingURL=paths.js.map
|
package/dist/utils/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;AAC9D,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AACrD,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAE9D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;AAEzD,gDAAgD;AAChD,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC;AAE3E,qEAAqE;AACrE,MAAM,gBAAgB,GAA2B;IAC/C,YAAY,EAAE,WAAW;CAC1B,CAAC;AAEF,0FAA0F;AAC1F,MAAM,UAAU,mBAAmB,CAAC,YAAoB;IACtD,MAAM,YAAY,GAChB,eAAe,IAAI,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;IAEpG,OAAO,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,YAAoB;IACnD,mDAAmD;IACnD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,cAAc,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;IAE/C,OAAO,cAAc,CAAC,UAAU,CAAC,cAAc,GAAG,GAAG,CAAC,IAAI,cAAc,KAAK,cAAc,CAAC;AAC9F,CAAC"}
|
package/dist/utils/paths.test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { isPublishedMode, CONTENT_ROOT, resolveTemplatePath } from './paths.js';
|
|
2
|
+
import { isPublishedMode, CONTENT_ROOT, resolveTemplatePath, isPathWithinRoot } from './paths.js';
|
|
3
3
|
describe('paths', () => {
|
|
4
4
|
it('isPublishedMode is boolean', () => {
|
|
5
5
|
expect(typeof isPublishedMode).toBe('boolean');
|
|
@@ -14,4 +14,25 @@ describe('paths', () => {
|
|
|
14
14
|
expect(result).toContain(CONTENT_ROOT);
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
|
+
describe('isPathWithinRoot', () => {
|
|
18
|
+
it('returns true for valid paths', () => {
|
|
19
|
+
expect(isPathWithinRoot('vite.config.ts')).toBe(true);
|
|
20
|
+
expect(isPathWithinRoot('docs/ARCHITECTURE.md')).toBe(true);
|
|
21
|
+
expect(isPathWithinRoot('src/main.tsx')).toBe(true);
|
|
22
|
+
expect(isPathWithinRoot('.gitignore')).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
it('returns false for path traversal attempts', () => {
|
|
25
|
+
expect(isPathWithinRoot('../../../etc/passwd')).toBe(false);
|
|
26
|
+
expect(isPathWithinRoot('../../secret')).toBe(false);
|
|
27
|
+
expect(isPathWithinRoot('/etc/passwd')).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
it('returns false for paths with embedded traversal', () => {
|
|
30
|
+
expect(isPathWithinRoot('docs/../../../etc/passwd')).toBe(false);
|
|
31
|
+
expect(isPathWithinRoot('src/../../outside')).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
it('returns true for paths with internal traversal that stay within root', () => {
|
|
34
|
+
expect(isPathWithinRoot('src/../package.json')).toBe(true);
|
|
35
|
+
expect(isPathWithinRoot('docs/../vite.config.ts')).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
17
38
|
//# sourceMappingURL=paths.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.test.js","sourceRoot":"","sources":["../../src/utils/paths.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"paths.test.js","sourceRoot":"","sources":["../../src/utils/paths.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAElG,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,OAAO,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,MAAM,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5D,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,MAAM,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjE,MAAM,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLAUDE.md generator - composes sections based on selected features.
|
|
3
|
+
*/
|
|
4
|
+
import type { FeatureId } from '../../../features/types.js';
|
|
5
|
+
/** Generates CLAUDE.md content based on selected features. */
|
|
6
|
+
export declare function generateClaudeMd(featureIds: FeatureId[], projectName: string, scripts: Record<string, string>): string;
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAe5D,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,SAAS,EAAE,EACvB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAgBR"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLAUDE.md generator - composes sections based on selected features.
|
|
3
|
+
*/
|
|
4
|
+
import { FEATURE } from '../../../constants.js';
|
|
5
|
+
import { generateHeader, generateCommandsSection, generateStructureSection, generateCodePatternsSection, generateUiSection, generateMobileSection, generateThemingSection, generateMcpSection, generateI18nSection, generateTestingSection, generateGotchasSection, } from './sections.js';
|
|
6
|
+
/** Generates CLAUDE.md content based on selected features. */
|
|
7
|
+
export function generateClaudeMd(featureIds, projectName, scripts) {
|
|
8
|
+
const sections = [
|
|
9
|
+
generateHeader(projectName),
|
|
10
|
+
generateCommandsSection(scripts),
|
|
11
|
+
generateStructureSection(featureIds),
|
|
12
|
+
generateCodePatternsSection(featureIds),
|
|
13
|
+
featureIds.includes(FEATURE.UI) && generateUiSection(),
|
|
14
|
+
featureIds.includes(FEATURE.MOBILE) && generateMobileSection(),
|
|
15
|
+
featureIds.includes(FEATURE.THEMING) && generateThemingSection(),
|
|
16
|
+
generateMcpSection(featureIds),
|
|
17
|
+
featureIds.includes(FEATURE.I18N) && generateI18nSection(),
|
|
18
|
+
featureIds.includes(FEATURE.TESTING) && generateTestingSection(),
|
|
19
|
+
generateGotchasSection(featureIds),
|
|
20
|
+
];
|
|
21
|
+
return sections.filter(Boolean).join('\n');
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,2BAA2B,EAC3B,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAC9B,UAAuB,EACvB,WAAmB,EACnB,OAA+B;IAE/B,MAAM,QAAQ,GAAG;QACf,cAAc,CAAC,WAAW,CAAC;QAC3B,uBAAuB,CAAC,OAAO,CAAC;QAChC,wBAAwB,CAAC,UAAU,CAAC;QACpC,2BAA2B,CAAC,UAAU,CAAC;QACvC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,iBAAiB,EAAE;QACtD,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,qBAAqB,EAAE;QAC9D,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,sBAAsB,EAAE;QAChE,kBAAkB,CAAC,UAAU,CAAC;QAC9B,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,mBAAmB,EAAE;QAC1D,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,sBAAsB,EAAE;QAChE,sBAAsB,CAAC,UAAU,CAAC;KACnC,CAAC;IAEF,OAAO,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLAUDE.md section generators - each function generates one section.
|
|
3
|
+
*/
|
|
4
|
+
import type { FeatureId } from '../../../features/types.js';
|
|
5
|
+
export declare function generateHeader(projectName: string): string;
|
|
6
|
+
export declare function generateCommandsSection(scripts: Record<string, string>): string;
|
|
7
|
+
export declare function generateStructureSection(featureIds: FeatureId[]): string;
|
|
8
|
+
export declare function generateCodePatternsSection(featureIds: FeatureId[]): string;
|
|
9
|
+
export declare function generateUiSection(): string;
|
|
10
|
+
export declare function generateMobileSection(): string;
|
|
11
|
+
export declare function generateThemingSection(): string;
|
|
12
|
+
export declare function generateMcpSection(featureIds: FeatureId[]): string;
|
|
13
|
+
export declare function generateI18nSection(): string;
|
|
14
|
+
export declare function generateTestingSection(): string;
|
|
15
|
+
export declare function generateGotchasSection(featureIds: FeatureId[]): string;
|
|
16
|
+
//# sourceMappingURL=sections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../../../../src/utils/scaffold/claude-md/sections.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAqB5D,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAI1D;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAe/E;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAuCxE;AAED,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAkB3E;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAmB1C;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAoC9C;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAuB/C;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAwClE;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAY5C;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAe/C;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAoBtE"}
|