@aramassa/ai-rules 0.1.1-npmjs.20250910072942
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-npmjs.md +37 -0
- package/README.md +37 -0
- package/artifact/chatmodes/Instruction Improve.md +142 -0
- package/artifact/chatmodes/Planning.md +173 -0
- package/artifact/instructions/git-rules.md +68 -0
- package/artifact/instructions/package-management.md +113 -0
- package/artifact/instructions/planning.md +54 -0
- package/artifact/instructions/python/workspace-management.md +673 -0
- package/artifact/instructions/python-cli.md +261 -0
- package/artifact/instructions/retrospective.md +32 -0
- package/artifact/instructions/rules/coding/nodejs.md +299 -0
- package/artifact/instructions/rules/coding/openai.md +39 -0
- package/artifact/instructions/rules/coding/typescript.md +92 -0
- package/artifact/instructions/rules/development/ansible.md +258 -0
- package/artifact/instructions/rules/development/code-quality-tools.md +181 -0
- package/artifact/instructions/rules/development/github.md +140 -0
- package/artifact/instructions/rules/development/npm-publish.md +108 -0
- package/artifact/instructions/rules/development/typescript-rollup-build.md +249 -0
- package/artifact/instructions/rules/development/typescript.md +46 -0
- package/artifact/instructions/rules/documentation/common.md +16 -0
- package/artifact/instructions/rules/documentation/docs-ai-external.md +12 -0
- package/artifact/instructions/rules/documentation/docs-ai-history.md +46 -0
- package/artifact/instructions/rules/documentation/docs-ai-internal.md +70 -0
- package/artifact/instructions/rules/documentation/docs-ai-learning.md +53 -0
- package/artifact/instructions/rules/documentation/docs.md +41 -0
- package/artifact/instructions/rules/documentation/github-protection.md +122 -0
- package/artifact/instructions/rules/test/e2e-bdd.md +31 -0
- package/artifact/instructions/rules/test/nodejs-test-restrictions.md +101 -0
- package/artifact/instructions/rules/test/timeout-configuration-typescript.md +67 -0
- package/artifact/instructions/rules/test/timeout-configuration.md +89 -0
- package/artifact/instructions/skel/common/change_plans/.gitkeep +0 -0
- package/artifact/instructions/skel/common/docs/.gitkeep +0 -0
- package/artifact/instructions/skel/common/docs_ai/.gitkeep +0 -0
- package/artifact/instructions/skel/common/skel/.gitkeep +0 -0
- package/artifact/instructions/skel/common/todo_plans/.gitkeep +0 -0
- package/artifact/instructions/skel/typescript/tsconfig.build.json +17 -0
- package/artifact/instructions/skel/typescript/tsconfig.json +117 -0
- package/artifact/instructions/skel/typescript/tsdoc.json +4 -0
- package/artifact/instructions/skel.md +88 -0
- package/artifact/instructions/todo_planning.md +25 -0
- package/artifact/instructions/tyding-up.md +30 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +10934 -0
- package/dist/filter.d.ts +8 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +72 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/optionValidator.d.ts +28 -0
- package/dist/optionValidator.d.ts.map +1 -0
- package/dist/optionValidator.js +29 -0
- package/dist/templateEngine.d.ts +55 -0
- package/dist/templateEngine.d.ts.map +1 -0
- package/dist/templateEngine.js +124 -0
- package/dist/utils/objectUtils.d.ts +11 -0
- package/dist/utils/objectUtils.d.ts.map +1 -0
- package/dist/utils/objectUtils.js +17 -0
- package/dist/utils/test/structureExtractors.d.ts +30 -0
- package/dist/utils/test/structureExtractors.d.ts.map +1 -0
- package/dist/utils/test/structureExtractors.js +164 -0
- package/dist/variableResolver.d.ts +68 -0
- package/dist/variableResolver.d.ts.map +1 -0
- package/dist/variableResolver.js +190 -0
- package/package.json +69 -0
- package/presets/README.md +109 -0
- package/presets/basic.yaml +14 -0
- package/presets/chatmodes.yaml +64 -0
- package/presets/docs-ai.yaml +7 -0
- package/presets/infrastructure-ansible.yaml +19 -0
- package/presets/typescript.yaml +16 -0
package/dist/filter.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { MarkdownFile } from "@internal/extract";
|
|
2
|
+
export interface FilterOptions {
|
|
3
|
+
types?: string[];
|
|
4
|
+
languages?: string[];
|
|
5
|
+
attrFilters: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function filterFiles(files: MarkdownFile[], options: FilterOptions): MarkdownFile[];
|
|
8
|
+
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAkDD,wBAAgB,WAAW,CACzB,KAAK,EAAE,YAAY,EAAE,EACrB,OAAO,EAAE,aAAa,GACrB,YAAY,EAAE,CA+BhB"}
|
package/dist/filter.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { getByDotNotation } from "./utils/objectUtils.js";
|
|
2
|
+
/**
|
|
3
|
+
* Checks if a value is considered empty (undefined, null, or empty string)
|
|
4
|
+
* @param value The value to check
|
|
5
|
+
* @returns true if the value is empty
|
|
6
|
+
*/
|
|
7
|
+
function isEmptyValue(value) {
|
|
8
|
+
return value === undefined || value === null || value === '';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Generic filter function for attribute matching
|
|
12
|
+
* @param value The value to check
|
|
13
|
+
* @param allowedValues The list of allowed values (empty string allowed for undefined/empty)
|
|
14
|
+
* @returns true if the value matches the filter criteria
|
|
15
|
+
*/
|
|
16
|
+
function matchesAttributeFilter(value, allowedValues) {
|
|
17
|
+
// Handle empty values
|
|
18
|
+
if (isEmptyValue(value)) {
|
|
19
|
+
return allowedValues.includes('');
|
|
20
|
+
}
|
|
21
|
+
// Handle array values - check if any element matches
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
return value.some(item => {
|
|
24
|
+
const stringValue = String(item);
|
|
25
|
+
return allowedValues.includes(stringValue);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// Handle single values
|
|
29
|
+
const stringValue = String(value);
|
|
30
|
+
return allowedValues.includes(stringValue);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Filters files based on attribute criteria
|
|
34
|
+
* @param files Array of markdown files to filter
|
|
35
|
+
* @param attributeName The attribute name to filter on
|
|
36
|
+
* @param allowedValues Array of allowed values for the attribute
|
|
37
|
+
* @returns Filtered array of files
|
|
38
|
+
*/
|
|
39
|
+
function filterByAttribute(files, attributeName, allowedValues) {
|
|
40
|
+
return files.filter(file => {
|
|
41
|
+
const value = file.attrs[attributeName];
|
|
42
|
+
return matchesAttributeFilter(value, allowedValues);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export function filterFiles(files, options) {
|
|
46
|
+
const { types, languages, attrFilters } = options;
|
|
47
|
+
let filteredFiles = files;
|
|
48
|
+
// Filter by type using generic function
|
|
49
|
+
if (types) {
|
|
50
|
+
filteredFiles = filterByAttribute(filteredFiles, 'type', types);
|
|
51
|
+
}
|
|
52
|
+
// Filter by language using generic function
|
|
53
|
+
if (languages) {
|
|
54
|
+
filteredFiles = filterByAttribute(filteredFiles, 'language', languages);
|
|
55
|
+
}
|
|
56
|
+
// Filter by custom attributes using dot notation
|
|
57
|
+
for (const attr of attrFilters) {
|
|
58
|
+
const [key, value = ''] = attr.split('=');
|
|
59
|
+
filteredFiles = filteredFiles.filter(f => {
|
|
60
|
+
const fileVal = getByDotNotation(f.attrs, key);
|
|
61
|
+
// Handle pipe-separated values for OR logic (from array filters)
|
|
62
|
+
if (value.includes('|')) {
|
|
63
|
+
const possibleValues = value.split('|');
|
|
64
|
+
return matchesAttributeFilter(fileVal, possibleValues);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return matchesAttributeFilter(fileVal, [value]);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return filteredFiles;
|
|
72
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare enum WriteMode {
|
|
2
|
+
APPEND = "append",
|
|
3
|
+
PREPEND = "prepend",
|
|
4
|
+
OVERWRITE = "overwrite"
|
|
5
|
+
}
|
|
6
|
+
export interface ExtractOptions {
|
|
7
|
+
srcDir: string;
|
|
8
|
+
outFile: string;
|
|
9
|
+
types?: string[];
|
|
10
|
+
languages?: string[];
|
|
11
|
+
attrFilters: string[];
|
|
12
|
+
title?: string;
|
|
13
|
+
mode: WriteMode;
|
|
14
|
+
attr?: Record<string, unknown>;
|
|
15
|
+
debug?: boolean;
|
|
16
|
+
vars?: string;
|
|
17
|
+
envFile?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface StatsOptions {
|
|
20
|
+
srcDir: string;
|
|
21
|
+
variables?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare class CliOptionValidator {
|
|
24
|
+
private static readonly ERROR_MESSAGES;
|
|
25
|
+
static validateExtractOptions(options: ExtractOptions): void;
|
|
26
|
+
static validateStatsOptions(options: StatsOptions): void;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=optionValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optionValidator.d.ts","sourceRoot":"","sources":["../src/optionValidator.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS;IACnB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,SAAS,cAAc;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAIpC;WAEY,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;WAYrD,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;CAKhE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export var WriteMode;
|
|
2
|
+
(function (WriteMode) {
|
|
3
|
+
WriteMode["APPEND"] = "append";
|
|
4
|
+
WriteMode["PREPEND"] = "prepend";
|
|
5
|
+
WriteMode["OVERWRITE"] = "overwrite";
|
|
6
|
+
})(WriteMode || (WriteMode = {}));
|
|
7
|
+
export class CliOptionValidator {
|
|
8
|
+
static validateExtractOptions(options) {
|
|
9
|
+
if (!options.srcDir) {
|
|
10
|
+
throw new Error(this.ERROR_MESSAGES.SRC_DIR_REQUIRED);
|
|
11
|
+
}
|
|
12
|
+
if (!options.outFile) {
|
|
13
|
+
throw new Error(this.ERROR_MESSAGES.OUT_FILE_REQUIRED);
|
|
14
|
+
}
|
|
15
|
+
if (!Object.values(WriteMode).includes(options.mode)) {
|
|
16
|
+
throw new Error(this.ERROR_MESSAGES.INVALID_MODE);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
static validateStatsOptions(options) {
|
|
20
|
+
if (!options.srcDir) {
|
|
21
|
+
throw new Error(this.ERROR_MESSAGES.SRC_DIR_REQUIRED);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
CliOptionValidator.ERROR_MESSAGES = {
|
|
26
|
+
SRC_DIR_REQUIRED: "Source directory (srcDir) is required",
|
|
27
|
+
OUT_FILE_REQUIRED: "Output file (outFile) is required",
|
|
28
|
+
INVALID_MODE: "Invalid mode. Must be one of: append, prepend, overwrite"
|
|
29
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template variable definition extracted from template content
|
|
3
|
+
*/
|
|
4
|
+
export interface TemplateVariable {
|
|
5
|
+
name: string;
|
|
6
|
+
defaultValue?: string;
|
|
7
|
+
required: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Options for template engine processing
|
|
11
|
+
*/
|
|
12
|
+
export interface TemplateEngineOptions {
|
|
13
|
+
variables: Record<string, string>;
|
|
14
|
+
strictMode?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Core template engine for processing variable substitution in markdown content
|
|
18
|
+
*/
|
|
19
|
+
export declare class TemplateEngine {
|
|
20
|
+
private static readonly VARIABLE_WITH_DEFAULT_REGEX;
|
|
21
|
+
private static readonly REQUIRED_VARIABLE_REGEX;
|
|
22
|
+
/**
|
|
23
|
+
* Parse template content to extract all variable definitions
|
|
24
|
+
* @param content Template content to parse
|
|
25
|
+
* @returns Array of template variables found
|
|
26
|
+
*/
|
|
27
|
+
parseTemplate(content: string): TemplateVariable[];
|
|
28
|
+
/**
|
|
29
|
+
* Render template content by substituting variables
|
|
30
|
+
* @param content Template content to render
|
|
31
|
+
* @param options Rendering options including variables
|
|
32
|
+
* @returns Rendered content with variables substituted
|
|
33
|
+
*/
|
|
34
|
+
renderTemplate(content: string, options: TemplateEngineOptions): string;
|
|
35
|
+
/**
|
|
36
|
+
* Validate that all required variables are provided
|
|
37
|
+
* @param content Template content to validate
|
|
38
|
+
* @param variables Available variables
|
|
39
|
+
* @throws Error if required variables are missing
|
|
40
|
+
*/
|
|
41
|
+
validateRequiredVariables(content: string, variables: Record<string, string>): void;
|
|
42
|
+
/**
|
|
43
|
+
* Check if content contains any template variables
|
|
44
|
+
* @param content Content to check
|
|
45
|
+
* @returns True if content contains template variables
|
|
46
|
+
*/
|
|
47
|
+
hasTemplateVariables(content: string): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Extract only the required variable names from content
|
|
50
|
+
* @param content Content to scan for required variables
|
|
51
|
+
* @returns Array of required variable names found
|
|
52
|
+
*/
|
|
53
|
+
extractRequiredVariables(content: string): string[];
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=templateEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templateEngine.d.ts","sourceRoot":"","sources":["../src/templateEngine.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,cAAc;IAEzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,2BAA2B,CAAuC;IAC1F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAA8B;IAE7E;;;;OAIG;IACI,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,EAAE;IAuCzD;;;;;OAKG;IACI,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,MAAM;IA8B9E;;;;;OAKG;IACI,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAkB1F;;;;OAIG;IACI,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAKrD;;;;OAIG;IACI,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;CAiB3D"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core template engine for processing variable substitution in markdown content
|
|
3
|
+
*/
|
|
4
|
+
export class TemplateEngine {
|
|
5
|
+
/**
|
|
6
|
+
* Parse template content to extract all variable definitions
|
|
7
|
+
* @param content Template content to parse
|
|
8
|
+
* @returns Array of template variables found
|
|
9
|
+
*/
|
|
10
|
+
parseTemplate(content) {
|
|
11
|
+
const variables = [];
|
|
12
|
+
const seenVariables = new Set();
|
|
13
|
+
// Parse variables with default values: ${VAR:default}
|
|
14
|
+
let match;
|
|
15
|
+
while ((match = TemplateEngine.VARIABLE_WITH_DEFAULT_REGEX.exec(content)) !== null) {
|
|
16
|
+
const [, name, defaultValue] = match;
|
|
17
|
+
if (!seenVariables.has(name)) {
|
|
18
|
+
variables.push({
|
|
19
|
+
name,
|
|
20
|
+
defaultValue,
|
|
21
|
+
required: false
|
|
22
|
+
});
|
|
23
|
+
seenVariables.add(name);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Reset regex for next use
|
|
27
|
+
TemplateEngine.VARIABLE_WITH_DEFAULT_REGEX.lastIndex = 0;
|
|
28
|
+
// Parse required variables: !{VAR}
|
|
29
|
+
while ((match = TemplateEngine.REQUIRED_VARIABLE_REGEX.exec(content)) !== null) {
|
|
30
|
+
const [, name] = match;
|
|
31
|
+
if (!seenVariables.has(name)) {
|
|
32
|
+
variables.push({
|
|
33
|
+
name,
|
|
34
|
+
required: true
|
|
35
|
+
});
|
|
36
|
+
seenVariables.add(name);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Reset regex for next use
|
|
40
|
+
TemplateEngine.REQUIRED_VARIABLE_REGEX.lastIndex = 0;
|
|
41
|
+
return variables;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Render template content by substituting variables
|
|
45
|
+
* @param content Template content to render
|
|
46
|
+
* @param options Rendering options including variables
|
|
47
|
+
* @returns Rendered content with variables substituted
|
|
48
|
+
*/
|
|
49
|
+
renderTemplate(content, options) {
|
|
50
|
+
// First validate required variables if in strict mode
|
|
51
|
+
if (options.strictMode) {
|
|
52
|
+
this.validateRequiredVariables(content, options.variables);
|
|
53
|
+
}
|
|
54
|
+
let result = content;
|
|
55
|
+
// Replace variables with default values: ${VAR:default}
|
|
56
|
+
result = result.replace(TemplateEngine.VARIABLE_WITH_DEFAULT_REGEX, (match, name, defaultValue) => {
|
|
57
|
+
return options.variables[name] ?? defaultValue;
|
|
58
|
+
});
|
|
59
|
+
// Replace required variables: !{VAR}
|
|
60
|
+
result = result.replace(TemplateEngine.REQUIRED_VARIABLE_REGEX, (match, name) => {
|
|
61
|
+
const value = options.variables[name];
|
|
62
|
+
if (value === undefined) {
|
|
63
|
+
if (options.strictMode) {
|
|
64
|
+
// This will be caught by the validation that happens before this
|
|
65
|
+
return match;
|
|
66
|
+
}
|
|
67
|
+
// In non-strict mode, leave the variable placeholder
|
|
68
|
+
return match;
|
|
69
|
+
}
|
|
70
|
+
return value;
|
|
71
|
+
});
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Validate that all required variables are provided
|
|
76
|
+
* @param content Template content to validate
|
|
77
|
+
* @param variables Available variables
|
|
78
|
+
* @throws Error if required variables are missing
|
|
79
|
+
*/
|
|
80
|
+
validateRequiredVariables(content, variables) {
|
|
81
|
+
const templateVars = this.parseTemplate(content);
|
|
82
|
+
const missingRequired = [];
|
|
83
|
+
for (const variable of templateVars) {
|
|
84
|
+
if (variable.required && variables[variable.name] === undefined) {
|
|
85
|
+
missingRequired.push(variable.name);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (missingRequired.length > 0) {
|
|
89
|
+
throw new Error(`Required variables are missing: ${missingRequired.join(', ')}\n` +
|
|
90
|
+
`Please provide values using --vars "${missingRequired.map(v => `${v}=value`).join(' ')}" or environment files.`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if content contains any template variables
|
|
95
|
+
* @param content Content to check
|
|
96
|
+
* @returns True if content contains template variables
|
|
97
|
+
*/
|
|
98
|
+
hasTemplateVariables(content) {
|
|
99
|
+
return TemplateEngine.VARIABLE_WITH_DEFAULT_REGEX.test(content) ||
|
|
100
|
+
TemplateEngine.REQUIRED_VARIABLE_REGEX.test(content);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Extract only the required variable names from content
|
|
104
|
+
* @param content Content to scan for required variables
|
|
105
|
+
* @returns Array of required variable names found
|
|
106
|
+
*/
|
|
107
|
+
extractRequiredVariables(content) {
|
|
108
|
+
const requiredVariables = [];
|
|
109
|
+
let match;
|
|
110
|
+
// Parse required variables: !{VAR}
|
|
111
|
+
while ((match = TemplateEngine.REQUIRED_VARIABLE_REGEX.exec(content)) !== null) {
|
|
112
|
+
const [, name] = match;
|
|
113
|
+
if (!requiredVariables.includes(name)) {
|
|
114
|
+
requiredVariables.push(name);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Reset regex for next use
|
|
118
|
+
TemplateEngine.REQUIRED_VARIABLE_REGEX.lastIndex = 0;
|
|
119
|
+
return requiredVariables;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Regular expressions for parsing template variables
|
|
123
|
+
TemplateEngine.VARIABLE_WITH_DEFAULT_REGEX = /\$\{([A-Z_][A-Z0-9_]*):([^}]*)\}/g;
|
|
124
|
+
TemplateEngine.REQUIRED_VARIABLE_REGEX = /!\{([A-Z_][A-Z0-9_]*)\}/g;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for object manipulation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Gets a value from an object using dot notation path
|
|
6
|
+
* @param obj The object to query
|
|
7
|
+
* @param path The dot notation path (e.g., "a.b.c")
|
|
8
|
+
* @returns The value at the path, or undefined if not found
|
|
9
|
+
*/
|
|
10
|
+
export declare function getByDotNotation(obj: unknown, path: string): unknown;
|
|
11
|
+
//# sourceMappingURL=objectUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objectUtils.d.ts","sourceRoot":"","sources":["../../src/utils/objectUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAOpE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for object manipulation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Gets a value from an object using dot notation path
|
|
6
|
+
* @param obj The object to query
|
|
7
|
+
* @param path The dot notation path (e.g., "a.b.c")
|
|
8
|
+
* @returns The value at the path, or undefined if not found
|
|
9
|
+
*/
|
|
10
|
+
export function getByDotNotation(obj, path) {
|
|
11
|
+
return path.split('.').reduce((o, k) => {
|
|
12
|
+
if (o && typeof o === 'object' && k in o) {
|
|
13
|
+
return o[k];
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}, obj);
|
|
17
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 指定した TypeScript ファイルからクラス・メソッド・プロパティの構造を抽出
|
|
3
|
+
*/
|
|
4
|
+
export declare function extractClassStructure(filePath: string): Record<string, {
|
|
5
|
+
methods: string[];
|
|
6
|
+
statics: string[];
|
|
7
|
+
properties: string[];
|
|
8
|
+
}>;
|
|
9
|
+
/**
|
|
10
|
+
* 指定した TypeScript ファイルから関数名を抽出(トップレベル関数とエクスポートされた関数のみ)
|
|
11
|
+
*/
|
|
12
|
+
export declare function extractFunctionStructure(filePath: string): string[];
|
|
13
|
+
/**
|
|
14
|
+
* Extract interface names and their members from a TypeScript file
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractInterfaceStructure(filePath: string): Record<string, {
|
|
17
|
+
properties: string[];
|
|
18
|
+
methods: string[];
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* Extract type alias names and, if the alias is an object type, its property names
|
|
22
|
+
*/
|
|
23
|
+
export declare function extractTypeAliasStructure(filePath: string): Record<string, {
|
|
24
|
+
properties: string[];
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Extract exported constant objects and their property names from a TypeScript file
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractConstantStructure(filePath: string): Record<string, string[]>;
|
|
30
|
+
//# sourceMappingURL=structureExtractors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structureExtractors.d.ts","sourceRoot":"","sources":["../../../src/utils/test/structureExtractors.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,GACf,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA2BhF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BnE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,GACf,MAAM,CAAC,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA4B7D;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,GACf,MAAM,CAAC,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA0B1C;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,GACf,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CA6C1B"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
/**
|
|
4
|
+
* 指定した TypeScript ファイルからクラス・メソッド・プロパティの構造を抽出
|
|
5
|
+
*/
|
|
6
|
+
export function extractClassStructure(filePath) {
|
|
7
|
+
const src = fs.readFileSync(filePath, "utf8");
|
|
8
|
+
const sourceFile = ts.createSourceFile(filePath, src, ts.ScriptTarget.Latest, true);
|
|
9
|
+
const classes = {};
|
|
10
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
11
|
+
if (ts.isClassDeclaration(node) && node.name) {
|
|
12
|
+
const className = node.name.text;
|
|
13
|
+
const methods = [];
|
|
14
|
+
const statics = [];
|
|
15
|
+
const properties = [];
|
|
16
|
+
node.members.forEach((member) => {
|
|
17
|
+
if (ts.isMethodDeclaration(member) && member.name && ts.isIdentifier(member.name)) {
|
|
18
|
+
if (member.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword)) {
|
|
19
|
+
statics.push(member.name.text);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
methods.push(member.name.text);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (ts.isPropertyDeclaration(member) && member.name && ts.isIdentifier(member.name)) {
|
|
26
|
+
properties.push(member.name.text);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
classes[className] = { methods, statics, properties };
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return classes;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 指定した TypeScript ファイルから関数名を抽出(トップレベル関数とエクスポートされた関数のみ)
|
|
36
|
+
*/
|
|
37
|
+
export function extractFunctionStructure(filePath) {
|
|
38
|
+
const src = fs.readFileSync(filePath, "utf8");
|
|
39
|
+
const sourceFile = ts.createSourceFile(filePath, src, ts.ScriptTarget.Latest, true);
|
|
40
|
+
const functions = [];
|
|
41
|
+
// トップレベルのみ探索する
|
|
42
|
+
sourceFile.forEachChild((node) => {
|
|
43
|
+
// トップレベルの function 宣言
|
|
44
|
+
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
45
|
+
functions.push(node.name.text);
|
|
46
|
+
}
|
|
47
|
+
// トップレベルの export const foo = () => {}
|
|
48
|
+
if (ts.isVariableStatement(node)) {
|
|
49
|
+
const isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
|
|
50
|
+
node.declarationList.declarations.forEach((declaration) => {
|
|
51
|
+
if (ts.isVariableDeclaration(declaration) &&
|
|
52
|
+
declaration.name &&
|
|
53
|
+
ts.isIdentifier(declaration.name) &&
|
|
54
|
+
declaration.initializer &&
|
|
55
|
+
ts.isArrowFunction(declaration.initializer)) {
|
|
56
|
+
// export されているもののみ抽出
|
|
57
|
+
if (isExported) {
|
|
58
|
+
functions.push(declaration.name.text);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return functions.sort();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Extract interface names and their members from a TypeScript file
|
|
68
|
+
*/
|
|
69
|
+
export function extractInterfaceStructure(filePath) {
|
|
70
|
+
const src = fs.readFileSync(filePath, "utf8");
|
|
71
|
+
const sourceFile = ts.createSourceFile(filePath, src, ts.ScriptTarget.Latest, true);
|
|
72
|
+
const interfaces = {};
|
|
73
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
74
|
+
if (ts.isInterfaceDeclaration(node) && node.name) {
|
|
75
|
+
const ifaceName = node.name.text;
|
|
76
|
+
const properties = [];
|
|
77
|
+
const methods = [];
|
|
78
|
+
node.members.forEach((member) => {
|
|
79
|
+
if (ts.isPropertySignature(member) && member.name && ts.isIdentifier(member.name)) {
|
|
80
|
+
properties.push(member.name.text);
|
|
81
|
+
}
|
|
82
|
+
if (ts.isMethodSignature(member) && member.name && ts.isIdentifier(member.name)) {
|
|
83
|
+
methods.push(member.name.text);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
interfaces[ifaceName] = {
|
|
87
|
+
properties: properties.sort(),
|
|
88
|
+
methods: methods.sort(),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
return interfaces;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Extract type alias names and, if the alias is an object type, its property names
|
|
96
|
+
*/
|
|
97
|
+
export function extractTypeAliasStructure(filePath) {
|
|
98
|
+
const src = fs.readFileSync(filePath, "utf8");
|
|
99
|
+
const sourceFile = ts.createSourceFile(filePath, src, ts.ScriptTarget.Latest, true);
|
|
100
|
+
const aliases = {};
|
|
101
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
102
|
+
if (ts.isTypeAliasDeclaration(node) && node.name) {
|
|
103
|
+
const aliasName = node.name.text;
|
|
104
|
+
const properties = [];
|
|
105
|
+
if (ts.isTypeLiteralNode(node.type)) {
|
|
106
|
+
node.type.members.forEach((member) => {
|
|
107
|
+
if (ts.isPropertySignature(member) && member.name && ts.isIdentifier(member.name)) {
|
|
108
|
+
properties.push(member.name.text);
|
|
109
|
+
}
|
|
110
|
+
if (ts.isMethodSignature(member) && member.name && ts.isIdentifier(member.name)) {
|
|
111
|
+
properties.push(member.name.text);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
aliases[aliasName] = { properties: properties.sort() };
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return aliases;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Extract exported constant objects and their property names from a TypeScript file
|
|
122
|
+
*/
|
|
123
|
+
export function extractConstantStructure(filePath) {
|
|
124
|
+
const src = fs.readFileSync(filePath, "utf8");
|
|
125
|
+
const sourceFile = ts.createSourceFile(filePath, src, ts.ScriptTarget.Latest, true);
|
|
126
|
+
const constants = {};
|
|
127
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
128
|
+
if (ts.isVariableStatement(node)) {
|
|
129
|
+
const isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
|
|
130
|
+
if (!isExported)
|
|
131
|
+
return;
|
|
132
|
+
node.declarationList.declarations.forEach((decl) => {
|
|
133
|
+
if (ts.isVariableDeclaration(decl) &&
|
|
134
|
+
decl.name &&
|
|
135
|
+
ts.isIdentifier(decl.name) &&
|
|
136
|
+
decl.initializer) {
|
|
137
|
+
let objLit;
|
|
138
|
+
if (ts.isObjectLiteralExpression(decl.initializer)) {
|
|
139
|
+
objLit = decl.initializer;
|
|
140
|
+
}
|
|
141
|
+
else if (ts.isAsExpression(decl.initializer) ||
|
|
142
|
+
ts.isTypeAssertionExpression(decl.initializer)) {
|
|
143
|
+
const expr = decl.initializer.expression;
|
|
144
|
+
if (ts.isObjectLiteralExpression(expr))
|
|
145
|
+
objLit = expr;
|
|
146
|
+
}
|
|
147
|
+
if (objLit) {
|
|
148
|
+
const props = [];
|
|
149
|
+
objLit.properties.forEach((prop) => {
|
|
150
|
+
if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
|
|
151
|
+
props.push(prop.name.text);
|
|
152
|
+
}
|
|
153
|
+
else if (ts.isShorthandPropertyAssignment(prop)) {
|
|
154
|
+
props.push(prop.name.text);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
constants[decl.name.text] = props;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
return constants;
|
|
164
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for variable resolution from multiple sources
|
|
3
|
+
*/
|
|
4
|
+
export interface VariableResolutionOptions {
|
|
5
|
+
cliVariables?: Record<string, string>;
|
|
6
|
+
recipeVariables?: Record<string, string>;
|
|
7
|
+
envFile?: string;
|
|
8
|
+
environmentVariables?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Variable resolver that handles collecting variables from multiple sources
|
|
12
|
+
* with proper priority order: CLI > recipe > .env > environment variables
|
|
13
|
+
*/
|
|
14
|
+
export declare class VariableResolver {
|
|
15
|
+
/**
|
|
16
|
+
* Resolve variables from multiple sources according to priority
|
|
17
|
+
* @param options Resolution options specifying sources
|
|
18
|
+
* @returns Merged variables with proper priority
|
|
19
|
+
*/
|
|
20
|
+
resolveVariables(options: VariableResolutionOptions): Promise<Record<string, string>>;
|
|
21
|
+
/**
|
|
22
|
+
* Load variables from .env file
|
|
23
|
+
* @param filePath Path to .env file
|
|
24
|
+
* @returns Variables loaded from file
|
|
25
|
+
*/
|
|
26
|
+
private loadEnvFile;
|
|
27
|
+
/**
|
|
28
|
+
* Parse .env file content into variables object
|
|
29
|
+
* @param content .env file content
|
|
30
|
+
* @returns Parsed variables
|
|
31
|
+
*/
|
|
32
|
+
private parseEnvContent;
|
|
33
|
+
/**
|
|
34
|
+
* Remove surrounding quotes from environment variable values
|
|
35
|
+
* @param value Value to unquote
|
|
36
|
+
* @returns Unquoted value
|
|
37
|
+
*/
|
|
38
|
+
private unquoteValue;
|
|
39
|
+
/**
|
|
40
|
+
* Get relevant environment variables (those that match template variable naming convention)
|
|
41
|
+
* @returns Environment variables that could be used as template variables
|
|
42
|
+
*/
|
|
43
|
+
private getEnvironmentVariables;
|
|
44
|
+
/**
|
|
45
|
+
* Merge variables from multiple sources with later sources taking precedence
|
|
46
|
+
* @param sources Variable objects in order of precedence (lowest to highest)
|
|
47
|
+
* @returns Merged variables object
|
|
48
|
+
*/
|
|
49
|
+
private mergeVariables;
|
|
50
|
+
/**
|
|
51
|
+
* Parse CLI variables string in key=value format
|
|
52
|
+
* @param varsString Comma-separated key=value pairs
|
|
53
|
+
* @returns Parsed variables object
|
|
54
|
+
*/
|
|
55
|
+
static parseCliVariables(varsString: string): Record<string, string>;
|
|
56
|
+
/**
|
|
57
|
+
* Get variables by source for display purposes
|
|
58
|
+
* @param options Options specifying which sources to check
|
|
59
|
+
* @returns Object with variables grouped by source
|
|
60
|
+
*/
|
|
61
|
+
getVariablesBySource(options: {
|
|
62
|
+
envFile?: string;
|
|
63
|
+
}): Promise<{
|
|
64
|
+
environment: Record<string, string>;
|
|
65
|
+
envFile: Record<string, string>;
|
|
66
|
+
}>;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=variableResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variableResolver.d.ts","sourceRoot":"","sources":["../src/variableResolver.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B;;;;OAIG;IACU,gBAAgB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IA+BlG;;;;OAIG;YACW,WAAW;IAazB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAwBvB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAYpB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAyC/B;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAItB;;;;OAIG;WACW,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IA+B3E;;;;OAIG;IACU,oBAAoB,CAAC,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QACxE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACjC,CAAC;CAiBH"}
|