@openinc/parse-server-opendash 3.19.2 → 3.20.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/dist/featuremap.json +1 -0
- package/dist/features/config/helper/isFeatureEnabled.d.ts +2 -1
- package/dist/features/documentation/config/defaults.d.ts +39 -0
- package/dist/features/documentation/config/defaults.js +142 -0
- package/dist/features/documentation/config/index.d.ts +1 -0
- package/dist/features/documentation/config/index.js +17 -0
- package/dist/features/documentation/core/Cleanup.d.ts +30 -0
- package/dist/features/documentation/core/Cleanup.js +134 -0
- package/dist/features/documentation/core/Converter.d.ts +9 -0
- package/dist/features/documentation/core/Converter.js +65 -0
- package/dist/features/documentation/core/Importer.d.ts +21 -0
- package/dist/features/documentation/core/Importer.js +133 -0
- package/dist/features/documentation/core/Organizer.d.ts +11 -0
- package/dist/features/documentation/core/Organizer.js +52 -0
- package/dist/features/documentation/core/index.d.ts +4 -0
- package/dist/features/documentation/core/index.js +20 -0
- package/dist/features/documentation/functions/importDocs.d.ts +2 -0
- package/dist/features/documentation/functions/importDocs.js +40 -0
- package/dist/features/documentation/index.d.ts +8 -0
- package/dist/features/documentation/index.js +34 -0
- package/dist/features/documentation/services/ConfigApplier.d.ts +11 -0
- package/dist/features/documentation/services/ConfigApplier.js +110 -0
- package/dist/features/documentation/services/ContentLoader.d.ts +6 -0
- package/dist/features/documentation/services/ContentLoader.js +40 -0
- package/dist/features/documentation/services/FeatureFilter.d.ts +34 -0
- package/dist/features/documentation/services/FeatureFilter.js +154 -0
- package/dist/features/documentation/services/GitHubClient.d.ts +43 -0
- package/dist/features/documentation/services/GitHubClient.js +140 -0
- package/dist/features/documentation/services/MetadataEnricher.d.ts +5 -0
- package/dist/features/documentation/services/MetadataEnricher.js +29 -0
- package/dist/features/documentation/services/StructureBuilder.d.ts +7 -0
- package/dist/features/documentation/services/StructureBuilder.js +43 -0
- package/dist/features/documentation/services/TreeNormalizer.d.ts +10 -0
- package/dist/features/documentation/services/TreeNormalizer.js +73 -0
- package/dist/features/documentation/services/index.d.ts +7 -0
- package/dist/features/documentation/services/index.js +23 -0
- package/dist/features/documentation/types/GitHubTypes.d.ts +25 -0
- package/dist/features/documentation/types/GitHubTypes.js +2 -0
- package/dist/features/documentation/types/StructureTypes.d.ts +114 -0
- package/dist/features/documentation/types/StructureTypes.js +2 -0
- package/dist/features/documentation/types/index.d.ts +2 -0
- package/dist/features/documentation/types/index.js +18 -0
- package/dist/functions/openinc-documentation-import-docs.d.ts +1 -0
- package/dist/functions/openinc-documentation-import-docs.js +23 -0
- package/dist/hooks/Documentation_Config.d.ts +1 -0
- package/dist/hooks/Documentation_Config.js +17 -0
- package/dist/index.js +3 -0
- package/dist/types/Documentation_Category.d.ts +6 -0
- package/dist/types/Documentation_Category.js +12 -0
- package/dist/types/Documentation_Config.d.ts +21 -0
- package/dist/types/Documentation_Config.js +29 -0
- package/dist/types/Documentation_Document.d.ts +6 -0
- package/dist/types/Documentation_Document.js +12 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +5 -3
- package/package.json +3 -1
- package/schema/Documentation_Category.json +9 -0
- package/schema/Documentation_Config.json +50 -0
- package/schema/Documentation_Document.json +9 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GitHubClient = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* GitHub API Client for fetching repository data
|
|
6
|
+
*/
|
|
7
|
+
class GitHubClient {
|
|
8
|
+
constructor(token) {
|
|
9
|
+
this.baseUrl = "https://api.github.com";
|
|
10
|
+
this.headers = {
|
|
11
|
+
Authorization: `Bearer ${token}`,
|
|
12
|
+
Accept: "application/vnd.github.v3+json",
|
|
13
|
+
"User-Agent": "OpenInc-Documentation-Importer",
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Validate the GitHub token
|
|
18
|
+
*/
|
|
19
|
+
async validateToken() {
|
|
20
|
+
const response = await fetch(`${this.baseUrl}/user`, {
|
|
21
|
+
headers: this.headers,
|
|
22
|
+
});
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
const error = await response.text();
|
|
25
|
+
throw new Error(`Invalid token: ${response.status} ${response.statusText} - ${error}`);
|
|
26
|
+
}
|
|
27
|
+
return response.json();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get repository information
|
|
31
|
+
*/
|
|
32
|
+
async getRepository(owner, repo) {
|
|
33
|
+
const response = await fetch(`${this.baseUrl}/repos/${owner}/${repo}`, {
|
|
34
|
+
headers: this.headers,
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
const error = await response.text();
|
|
38
|
+
throw new Error(`Failed to access repository: ${response.status} ${response.statusText} - ${error}`);
|
|
39
|
+
}
|
|
40
|
+
return response.json();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get all branches for a repository
|
|
44
|
+
*/
|
|
45
|
+
async getBranches(owner, repo) {
|
|
46
|
+
const response = await fetch(`${this.baseUrl}/repos/${owner}/${repo}/branches`, {
|
|
47
|
+
headers: this.headers,
|
|
48
|
+
});
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw new Error(`Failed to fetch branches: ${response.status} ${response.statusText}`);
|
|
51
|
+
}
|
|
52
|
+
return response.json();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get a specific branch
|
|
56
|
+
*/
|
|
57
|
+
async getBranch(owner, repo, branch) {
|
|
58
|
+
const response = await fetch(`${this.baseUrl}/repos/${owner}/${repo}/branches/${branch}`, {
|
|
59
|
+
headers: this.headers,
|
|
60
|
+
});
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
const error = await response.text();
|
|
63
|
+
throw new Error(`Failed to fetch branch '${branch}': ${response.status} ${response.statusText} - ${error}`);
|
|
64
|
+
}
|
|
65
|
+
return response.json();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get repository tree (file structure)
|
|
69
|
+
*/
|
|
70
|
+
async getTree(owner, repo, sha, recursive = true) {
|
|
71
|
+
const url = `${this.baseUrl}/repos/${owner}/${repo}/git/trees/${sha}${recursive ? "?recursive=1" : ""}`;
|
|
72
|
+
const response = await fetch(url, {
|
|
73
|
+
headers: this.headers,
|
|
74
|
+
});
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
throw new Error(`Failed to fetch repository tree: ${response.status} ${response.statusText}`);
|
|
77
|
+
}
|
|
78
|
+
return response.json();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get file content
|
|
82
|
+
*/
|
|
83
|
+
async getFileContent(owner, repo, path, ref) {
|
|
84
|
+
const url = `${this.baseUrl}/repos/${owner}/${repo}/contents/${path}${ref ? `?ref=${ref}` : ""}`;
|
|
85
|
+
const response = await fetch(url, {
|
|
86
|
+
headers: this.headers,
|
|
87
|
+
});
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
throw new Error(`Failed to fetch file content: ${response.status} ${response.statusText}`);
|
|
90
|
+
}
|
|
91
|
+
return response.json();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get the last commit information for a specific file
|
|
95
|
+
*/
|
|
96
|
+
async getFileLastCommit(owner, repo, path, ref) {
|
|
97
|
+
const url = `${this.baseUrl}/repos/${owner}/${repo}/commits?path=${encodeURIComponent(path)}&per_page=1${ref ? `&sha=${ref}` : ""}`;
|
|
98
|
+
const response = await fetch(url, {
|
|
99
|
+
headers: this.headers,
|
|
100
|
+
});
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
throw new Error(`Failed to fetch file commit info: ${response.status} ${response.statusText}`);
|
|
103
|
+
}
|
|
104
|
+
const commits = (await response.json());
|
|
105
|
+
return commits.length > 0 ? commits[0] : null;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get commit information for multiple files in batch
|
|
109
|
+
*/
|
|
110
|
+
async getMultipleFileCommits(owner, repo, paths, ref) {
|
|
111
|
+
const commitMap = new Map();
|
|
112
|
+
// Process files in batches to avoid rate limiting
|
|
113
|
+
const batchSize = 5;
|
|
114
|
+
for (let i = 0; i < paths.length; i += batchSize) {
|
|
115
|
+
const batch = paths.slice(i, i + batchSize);
|
|
116
|
+
const promises = batch.map(async (path) => {
|
|
117
|
+
try {
|
|
118
|
+
const commit = await this.getFileLastCommit(owner, repo, path, ref);
|
|
119
|
+
return { path, commit };
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.warn(`⚠️ Failed to get commit info for ${path}:`, error);
|
|
123
|
+
return { path, commit: null };
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
const results = await Promise.all(promises);
|
|
127
|
+
results.forEach(({ path, commit }) => {
|
|
128
|
+
if (commit) {
|
|
129
|
+
commitMap.set(path, commit);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
// Small delay to be respectful to GitHub API
|
|
133
|
+
if (i + batchSize < paths.length) {
|
|
134
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return commitMap;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.GitHubClient = GitHubClient;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { DocumentationFile } from "../types";
|
|
2
|
+
import { GitHubClient } from "./GitHubClient";
|
|
3
|
+
export declare class MetadataEnricher {
|
|
4
|
+
static enrichCommits(files: DocumentationFile[], githubClient: GitHubClient, owner: string, repo: string, branch?: string, rootPath?: string): Promise<void>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MetadataEnricher = void 0;
|
|
4
|
+
class MetadataEnricher {
|
|
5
|
+
static async enrichCommits(files, githubClient, owner, repo, branch, rootPath) {
|
|
6
|
+
const normalizedRoot = rootPath?.replace(/^\/+/g, "").replace(/\/+$/g, "");
|
|
7
|
+
const fullPaths = files.map((f) => normalizedRoot ? `${normalizedRoot}/${f.path}` : f.path);
|
|
8
|
+
try {
|
|
9
|
+
const commitMap = await githubClient.getMultipleFileCommits(owner, repo, fullPaths, branch);
|
|
10
|
+
let enriched = 0;
|
|
11
|
+
files.forEach((file, idx) => {
|
|
12
|
+
const commit = commitMap.get(fullPaths[idx]);
|
|
13
|
+
if (commit?.commit) {
|
|
14
|
+
file.lastModified = new Date(commit.commit.author.date);
|
|
15
|
+
file.lastModifiedBy = commit.commit.author.name;
|
|
16
|
+
file.lastCommitSha = commit.sha;
|
|
17
|
+
file.lastCommitMessage = commit.commit.message.split("\n")[0];
|
|
18
|
+
if (!file.fileLastModifiedAt)
|
|
19
|
+
file.fileLastModifiedAt = file.lastModified;
|
|
20
|
+
enriched++;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
console.warn("Failed to fetch commit information:", e);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.MetadataEnricher = MetadataEnricher;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DocumentationFolder, DocumentationFile, FolderConfig } from "../types";
|
|
2
|
+
export declare class StructureBuilder {
|
|
3
|
+
static build(files: DocumentationFile[], rootPath?: string, defaultFolderConfig?: Partial<FolderConfig>): {
|
|
4
|
+
root: DocumentationFolder;
|
|
5
|
+
configFiles: DocumentationFile[];
|
|
6
|
+
};
|
|
7
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StructureBuilder = void 0;
|
|
4
|
+
class StructureBuilder {
|
|
5
|
+
static build(files, rootPath, defaultFolderConfig) {
|
|
6
|
+
const root = {
|
|
7
|
+
name: rootPath || "root",
|
|
8
|
+
path: "",
|
|
9
|
+
files: [],
|
|
10
|
+
subfolders: new Map(),
|
|
11
|
+
config: { ...defaultFolderConfig },
|
|
12
|
+
};
|
|
13
|
+
const configFiles = [];
|
|
14
|
+
for (const file of files) {
|
|
15
|
+
const pathParts = file.path.split("/");
|
|
16
|
+
// folder navigation (all but last segment)
|
|
17
|
+
let current = root;
|
|
18
|
+
for (let i = 0; i < pathParts.length - 1; i++) {
|
|
19
|
+
const folderName = pathParts[i];
|
|
20
|
+
const folderPath = pathParts.slice(0, i + 1).join("/");
|
|
21
|
+
if (!current.subfolders.has(folderName)) {
|
|
22
|
+
current.subfolders.set(folderName, {
|
|
23
|
+
name: folderName,
|
|
24
|
+
path: folderPath,
|
|
25
|
+
files: [],
|
|
26
|
+
subfolders: new Map(),
|
|
27
|
+
config: { ...defaultFolderConfig },
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
current = current.subfolders.get(folderName);
|
|
31
|
+
}
|
|
32
|
+
// classify file
|
|
33
|
+
if (file.originalFilename === "config.json") {
|
|
34
|
+
configFiles.push(file);
|
|
35
|
+
}
|
|
36
|
+
else if (file.extension === "md") {
|
|
37
|
+
current.files.push(file);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return { root, configFiles };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.StructureBuilder = StructureBuilder;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { GitHubTreeResponse, DocumentationFile, FileFilterOptions } from "../types";
|
|
2
|
+
/** Handles path normalization, root trimming and initial file object creation + filtering. */
|
|
3
|
+
export declare class TreeNormalizer {
|
|
4
|
+
static normalize(treeData: GitHubTreeResponse, rootPath?: string, fileFilter?: FileFilterOptions): {
|
|
5
|
+
files: DocumentationFile[];
|
|
6
|
+
normalizedRootPath: string;
|
|
7
|
+
};
|
|
8
|
+
private static shouldIncludeFile;
|
|
9
|
+
private static matchesPattern;
|
|
10
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TreeNormalizer = void 0;
|
|
4
|
+
/** Handles path normalization, root trimming and initial file object creation + filtering. */
|
|
5
|
+
class TreeNormalizer {
|
|
6
|
+
static normalize(treeData, rootPath, fileFilter) {
|
|
7
|
+
const normalizedRootPath = rootPath
|
|
8
|
+
? rootPath.replace(/^\/+/g, "").replace(/\/+$/g, "")
|
|
9
|
+
: "";
|
|
10
|
+
const rootPrefix = normalizedRootPath ? normalizedRootPath + "/" : "";
|
|
11
|
+
const files = [];
|
|
12
|
+
for (const item of treeData.tree) {
|
|
13
|
+
if (item.type !== "blob")
|
|
14
|
+
continue;
|
|
15
|
+
if (normalizedRootPath && !item.path.startsWith(rootPrefix))
|
|
16
|
+
continue;
|
|
17
|
+
let relativePath = item.path;
|
|
18
|
+
if (normalizedRootPath)
|
|
19
|
+
relativePath = item.path.substring(rootPrefix.length);
|
|
20
|
+
if (!relativePath)
|
|
21
|
+
continue;
|
|
22
|
+
const pathParts = relativePath.split("/");
|
|
23
|
+
const fileName = pathParts[pathParts.length - 1];
|
|
24
|
+
const extension = fileName.includes(".")
|
|
25
|
+
? (fileName.split(".").pop() || "").toLowerCase()
|
|
26
|
+
: "";
|
|
27
|
+
const baseName = extension
|
|
28
|
+
? fileName.slice(0, fileName.lastIndexOf("."))
|
|
29
|
+
: fileName;
|
|
30
|
+
const file = {
|
|
31
|
+
name: baseName,
|
|
32
|
+
originalFilename: fileName,
|
|
33
|
+
path: relativePath,
|
|
34
|
+
sha: item.sha,
|
|
35
|
+
size: item.size,
|
|
36
|
+
extension,
|
|
37
|
+
url: item.url,
|
|
38
|
+
};
|
|
39
|
+
if (fileFilter && !this.shouldIncludeFile(file, fileFilter))
|
|
40
|
+
continue;
|
|
41
|
+
files.push(file);
|
|
42
|
+
}
|
|
43
|
+
return { files, normalizedRootPath };
|
|
44
|
+
}
|
|
45
|
+
static shouldIncludeFile(file, filter) {
|
|
46
|
+
if (filter.excludeExtensions?.includes(file.extension))
|
|
47
|
+
return false;
|
|
48
|
+
if (filter.includeExtensions?.length &&
|
|
49
|
+
!filter.includeExtensions.includes(file.extension))
|
|
50
|
+
return false;
|
|
51
|
+
if (filter.excludePaths?.length) {
|
|
52
|
+
for (const p of filter.excludePaths)
|
|
53
|
+
if (this.matchesPattern(file.path, p))
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (filter.includePaths?.length) {
|
|
57
|
+
let inc = false;
|
|
58
|
+
for (const p of filter.includePaths)
|
|
59
|
+
if (this.matchesPattern(file.path, p)) {
|
|
60
|
+
inc = true;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
if (!inc)
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
static matchesPattern(path, pattern) {
|
|
69
|
+
const regexPattern = pattern.replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
70
|
+
return new RegExp(`^${regexPattern}$`, "i").test(path);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.TreeNormalizer = TreeNormalizer;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./GitHubClient"), exports);
|
|
18
|
+
__exportStar(require("./FeatureFilter"), exports);
|
|
19
|
+
__exportStar(require("./ConfigApplier"), exports);
|
|
20
|
+
__exportStar(require("./ContentLoader"), exports);
|
|
21
|
+
__exportStar(require("./MetadataEnricher"), exports);
|
|
22
|
+
__exportStar(require("./StructureBuilder"), exports);
|
|
23
|
+
__exportStar(require("./TreeNormalizer"), exports);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type GitHubTreeItem = {
|
|
2
|
+
path: string;
|
|
3
|
+
mode: string;
|
|
4
|
+
type: "blob" | "tree";
|
|
5
|
+
sha: string;
|
|
6
|
+
size?: number;
|
|
7
|
+
url: string;
|
|
8
|
+
};
|
|
9
|
+
export type GitHubTreeResponse = {
|
|
10
|
+
sha: string;
|
|
11
|
+
url: string;
|
|
12
|
+
tree: GitHubTreeItem[];
|
|
13
|
+
truncated: boolean;
|
|
14
|
+
};
|
|
15
|
+
export type GitHubBranch = {
|
|
16
|
+
name: string;
|
|
17
|
+
commit: {
|
|
18
|
+
sha: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export type GitHubRepository = {
|
|
22
|
+
name: string;
|
|
23
|
+
private: boolean;
|
|
24
|
+
default_branch: string;
|
|
25
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Feature } from "../../config/helper/isFeatureEnabled";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for an individual file within a documentation folder.
|
|
4
|
+
*/
|
|
5
|
+
export type FileConfig = {
|
|
6
|
+
/** Sort order for this file (lower first). Defaults to 999 if not provided. */
|
|
7
|
+
order?: number;
|
|
8
|
+
/** Icon identifier (e.g., fa:file). Defaults to fa:file */
|
|
9
|
+
icon?: string;
|
|
10
|
+
/** Optional display title overriding file name */
|
|
11
|
+
title?: string;
|
|
12
|
+
/** Location Pattern */
|
|
13
|
+
locationPattern?: string;
|
|
14
|
+
/** locations */
|
|
15
|
+
locations?: string[];
|
|
16
|
+
/** Optional feature flag controlling visibility */
|
|
17
|
+
feature?: Feature;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Configuration for a documentation folder (from config.json)
|
|
21
|
+
*/
|
|
22
|
+
export type FolderConfig = {
|
|
23
|
+
/** Display title for the folder (overrides folder name) */
|
|
24
|
+
title?: string;
|
|
25
|
+
/** Sort order for this folder (lower numbers first) */
|
|
26
|
+
order?: number;
|
|
27
|
+
/** Icon identifier for display */
|
|
28
|
+
icon?: string;
|
|
29
|
+
/** Per-file configuration map (key = file name without extension) */
|
|
30
|
+
files?: Record<string, FileConfig>;
|
|
31
|
+
/** Optional feature flag controlling the entire folder */
|
|
32
|
+
feature?: Feature;
|
|
33
|
+
};
|
|
34
|
+
export type DocumentationFile = {
|
|
35
|
+
/** Base name without extension */
|
|
36
|
+
name: string;
|
|
37
|
+
/** Original filename including extension */
|
|
38
|
+
originalFilename?: string;
|
|
39
|
+
path: string;
|
|
40
|
+
sha: string;
|
|
41
|
+
size?: number;
|
|
42
|
+
extension: string;
|
|
43
|
+
url: string;
|
|
44
|
+
lastModified?: Date;
|
|
45
|
+
lastModifiedBy?: string;
|
|
46
|
+
lastCommitSha?: string;
|
|
47
|
+
lastCommitMessage?: string;
|
|
48
|
+
/** Raw textual content of the file (decoded UTF-8 for text-based files) */
|
|
49
|
+
content?: string;
|
|
50
|
+
/** Timestamp from source control representing when the source was last modified (alias of lastModified for persistence clarity) */
|
|
51
|
+
fileLastModifiedAt?: Date;
|
|
52
|
+
/** File-specific configuration (inherited from parent folder config.files entry) */
|
|
53
|
+
config?: FileConfig;
|
|
54
|
+
};
|
|
55
|
+
export type DocumentationFolder = {
|
|
56
|
+
name: string;
|
|
57
|
+
path: string;
|
|
58
|
+
files: DocumentationFile[];
|
|
59
|
+
subfolders: Map<string, DocumentationFolder>;
|
|
60
|
+
/** Configuration from config.json file or default config (always present) */
|
|
61
|
+
config: FolderConfig;
|
|
62
|
+
};
|
|
63
|
+
export type DocumentationStructure = {
|
|
64
|
+
root: DocumentationFolder;
|
|
65
|
+
allFiles: DocumentationFile[];
|
|
66
|
+
filesByExtension: Map<string, DocumentationFile[]>;
|
|
67
|
+
};
|
|
68
|
+
export type ImportOptions = {
|
|
69
|
+
branch?: string;
|
|
70
|
+
repository: string;
|
|
71
|
+
organization: string;
|
|
72
|
+
token: string;
|
|
73
|
+
fileFilter?: FileFilterOptions;
|
|
74
|
+
/** Root path within the repository to start from (e.g., "docs" to start from docs folder) */
|
|
75
|
+
rootPath?: string;
|
|
76
|
+
/** Default folder configuration to apply to folders without config.json */
|
|
77
|
+
defaultFolderConfig?: Partial<FolderConfig>;
|
|
78
|
+
/** If provided, skip calling getBranch() and use this commit SHA directly (e.g., provided by external scheduler) */
|
|
79
|
+
preResolvedCommitSha?: string;
|
|
80
|
+
};
|
|
81
|
+
export type FileFilterOptions = {
|
|
82
|
+
/** Array of file extensions to include (without dots). If not provided, all files are included. */
|
|
83
|
+
includeExtensions?: string[];
|
|
84
|
+
/** Array of file extensions to exclude (without dots). Takes precedence over includeExtensions. */
|
|
85
|
+
excludeExtensions?: string[];
|
|
86
|
+
/** Path patterns to include (supports wildcards) */
|
|
87
|
+
includePaths?: string[];
|
|
88
|
+
/** Path patterns to exclude (supports wildcards) */
|
|
89
|
+
excludePaths?: string[];
|
|
90
|
+
};
|
|
91
|
+
export type ImportResult = {
|
|
92
|
+
/** Documentation structure for this import. Undefined when skipped (no new commit). */
|
|
93
|
+
structure?: DocumentationStructure;
|
|
94
|
+
metadata: {
|
|
95
|
+
totalFiles: number;
|
|
96
|
+
fileTypes: string[];
|
|
97
|
+
importedAt: Date;
|
|
98
|
+
repository: string;
|
|
99
|
+
branch: string;
|
|
100
|
+
/** Latest commit SHA observed for the branch at import time */
|
|
101
|
+
commitSha: string;
|
|
102
|
+
/** Previously imported commit SHA (if any) */
|
|
103
|
+
previousCommitSha?: string;
|
|
104
|
+
/** Indicates the import was skipped because the commit SHA is unchanged */
|
|
105
|
+
skipped?: boolean;
|
|
106
|
+
/** Reason for skipping (e.g., 'unchanged') */
|
|
107
|
+
skipReason?: string;
|
|
108
|
+
/** Cleanup information when old documentation was removed */
|
|
109
|
+
cleanup?: {
|
|
110
|
+
deletedDocuments: number;
|
|
111
|
+
deletedCategories: number;
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./GitHubTypes"), exports);
|
|
18
|
+
__exportStar(require("./StructureTypes"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function init(name: string): Promise<void>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.init = init;
|
|
4
|
+
const config_1 = require("../features/config");
|
|
5
|
+
const importDocs_1 = require("../features/documentation/functions/importDocs");
|
|
6
|
+
async function init(name) {
|
|
7
|
+
Parse.Cloud.define(name, async function (request) {
|
|
8
|
+
if (!request.master)
|
|
9
|
+
return { success: false, error: "Master key is required" };
|
|
10
|
+
try {
|
|
11
|
+
if ((0, config_1.isFeatureEnabled)("DOCUMENTATION")) {
|
|
12
|
+
await (0, importDocs_1.importDocs)();
|
|
13
|
+
return { status: "ok" };
|
|
14
|
+
}
|
|
15
|
+
console.log("Feature DOCUMENTATION is disabled");
|
|
16
|
+
return { status: "feature_disabled" };
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
console.error("Error in importDocs:", e);
|
|
20
|
+
return { status: "error", error: e };
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function init(): Promise<void>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.init = init;
|
|
4
|
+
const __1 = require("..");
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
async function init() {
|
|
7
|
+
(0, __1.beforeSaveHook)(types_1.Documentation_Config, async (request) => {
|
|
8
|
+
const { object, original, user } = request;
|
|
9
|
+
await (0, __1.defaultHandler)(request);
|
|
10
|
+
await (0, __1.defaultAclHandler)(request);
|
|
11
|
+
// TODO
|
|
12
|
+
});
|
|
13
|
+
(0, __1.afterSaveHook)(types_1.Documentation_Config, async (request) => {
|
|
14
|
+
const { object, original, user } = request;
|
|
15
|
+
// TODO
|
|
16
|
+
});
|
|
17
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -42,6 +42,7 @@ const Core_Email_1 = require("./hooks/Core_Email");
|
|
|
42
42
|
const openservice_1 = require("./features/openservice");
|
|
43
43
|
const _init_1 = require("./functions/_init");
|
|
44
44
|
const _init_2 = require("./hooks/_init");
|
|
45
|
+
const importDocs_1 = require("./features/documentation/functions/importDocs");
|
|
45
46
|
dayjs_1.default.extend(objectSupport_1.default);
|
|
46
47
|
dayjs_1.default.extend(weekday_1.default);
|
|
47
48
|
dayjs_1.default.extend(dayOfYear_1.default);
|
|
@@ -96,6 +97,8 @@ async function init() {
|
|
|
96
97
|
await (0, settings_1.initUserSettings)();
|
|
97
98
|
if ((0, config_1.isFeatureEnabled)("MAINTENANCE"))
|
|
98
99
|
await (0, openservice_1.init)();
|
|
100
|
+
if ((0, config_1.isFeatureEnabled)("DOCUMENTATION"))
|
|
101
|
+
await (0, importDocs_1.importDocs)();
|
|
99
102
|
}
|
|
100
103
|
async function initTranslations() {
|
|
101
104
|
// try {
|
|
@@ -5,7 +5,9 @@ export interface Documentation_CategoryAttributes {
|
|
|
5
5
|
objectId: string;
|
|
6
6
|
createdAt: Date;
|
|
7
7
|
updatedAt: Date;
|
|
8
|
+
gitPath?: string;
|
|
8
9
|
icon?: string;
|
|
10
|
+
isDefault: boolean;
|
|
9
11
|
name: string;
|
|
10
12
|
order: number;
|
|
11
13
|
parent?: Documentation_Category;
|
|
@@ -15,8 +17,12 @@ export interface Documentation_CategoryAttributes {
|
|
|
15
17
|
export declare class Documentation_Category extends Parse.Object<Documentation_CategoryAttributes> {
|
|
16
18
|
static className: string;
|
|
17
19
|
constructor(data?: Partial<Documentation_CategoryAttributes>);
|
|
20
|
+
get gitPath(): string | undefined;
|
|
21
|
+
set gitPath(value: string | undefined);
|
|
18
22
|
get icon(): string | undefined;
|
|
19
23
|
set icon(value: string | undefined);
|
|
24
|
+
get isDefault(): boolean;
|
|
25
|
+
set isDefault(value: boolean);
|
|
20
26
|
get name(): string;
|
|
21
27
|
set name(value: string);
|
|
22
28
|
get order(): number;
|
|
@@ -5,12 +5,24 @@ class Documentation_Category extends Parse.Object {
|
|
|
5
5
|
constructor(data) {
|
|
6
6
|
super("OD3_Documentation_Category", data);
|
|
7
7
|
}
|
|
8
|
+
get gitPath() {
|
|
9
|
+
return super.get("gitPath");
|
|
10
|
+
}
|
|
11
|
+
set gitPath(value) {
|
|
12
|
+
super.set("gitPath", value);
|
|
13
|
+
}
|
|
8
14
|
get icon() {
|
|
9
15
|
return super.get("icon");
|
|
10
16
|
}
|
|
11
17
|
set icon(value) {
|
|
12
18
|
super.set("icon", value);
|
|
13
19
|
}
|
|
20
|
+
get isDefault() {
|
|
21
|
+
return super.get("isDefault");
|
|
22
|
+
}
|
|
23
|
+
set isDefault(value) {
|
|
24
|
+
super.set("isDefault", value);
|
|
25
|
+
}
|
|
14
26
|
get name() {
|
|
15
27
|
return super.get("name");
|
|
16
28
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { _User } from "./_User";
|
|
2
|
+
import { Tenant } from "./Tenant";
|
|
3
|
+
export interface Documentation_ConfigAttributes {
|
|
4
|
+
id: string;
|
|
5
|
+
objectId: string;
|
|
6
|
+
createdAt: Date;
|
|
7
|
+
updatedAt: Date;
|
|
8
|
+
lastCommitSha?: string;
|
|
9
|
+
tenant?: Tenant;
|
|
10
|
+
user?: _User;
|
|
11
|
+
}
|
|
12
|
+
export declare class Documentation_Config extends Parse.Object<Documentation_ConfigAttributes> {
|
|
13
|
+
static className: string;
|
|
14
|
+
constructor(data?: Partial<Documentation_ConfigAttributes>);
|
|
15
|
+
get lastCommitSha(): string | undefined;
|
|
16
|
+
set lastCommitSha(value: string | undefined);
|
|
17
|
+
get tenant(): Tenant | undefined;
|
|
18
|
+
set tenant(value: Tenant | undefined);
|
|
19
|
+
get user(): _User | undefined;
|
|
20
|
+
set user(value: _User | undefined);
|
|
21
|
+
}
|