@jmruthers/pace-core 0.5.183 → 0.5.185
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/CHANGELOG.md +38 -0
- package/README.md +60 -1
- package/core-usage-manifest.json +312 -0
- package/dist/{DataTable-QAB34V6K.js → DataTable-IX2NBUTP.js} +6 -6
- package/dist/{DataTable-Bz8ffqyA.d.ts → DataTable-Z9NLVJh0.d.ts} +1 -1
- package/dist/{index-Bl--n7-T.d.ts → PublicPageProvider-BABf6JCh.d.ts} +21 -10
- package/dist/{UnifiedAuthProvider-7F6T4B6K.js → UnifiedAuthProvider-A4BCQRJY.js} +4 -2
- package/dist/{UnifiedAuthProvider-F86d7dSi.d.ts → UnifiedAuthProvider-BG0AL5eE.d.ts} +2 -1
- package/dist/{api-ROMBCNKU.js → api-BMFCXVQX.js} +2 -2
- package/dist/{chunk-RA3JUFMW.js → chunk-445GEP27.js} +154 -4
- package/dist/{chunk-RA3JUFMW.js.map → chunk-445GEP27.js.map} +1 -1
- package/dist/{chunk-CSOFYHAG.js → chunk-AISXLWGZ.js} +374 -60
- package/dist/chunk-AISXLWGZ.js.map +1 -0
- package/dist/{chunk-FUEYYMX5.js → chunk-FXFJRTKI.js} +24 -3
- package/dist/chunk-FXFJRTKI.js.map +1 -0
- package/dist/{chunk-QETLRQI6.js → chunk-HC67NW5K.js} +380 -360
- package/dist/chunk-HC67NW5K.js.map +1 -0
- package/dist/chunk-HESYZWZW.js +388 -0
- package/dist/chunk-HESYZWZW.js.map +1 -0
- package/dist/{chunk-QUVSNGIP.js → chunk-HGPQUCBC.js} +34 -9
- package/dist/{chunk-QUVSNGIP.js.map → chunk-HGPQUCBC.js.map} +1 -1
- package/dist/{chunk-UHNYIBXL.js → chunk-IXSNYUCT.js} +1 -1
- package/dist/chunk-IXSNYUCT.js.map +1 -0
- package/dist/{chunk-MI7HBHN3.js → chunk-MX3EIJGQ.js} +4 -3
- package/dist/{chunk-MI7HBHN3.js.map → chunk-MX3EIJGQ.js.map} +1 -1
- package/dist/{chunk-PWAHJW4G.js → chunk-OKI34GZD.js} +86 -33
- package/dist/chunk-OKI34GZD.js.map +1 -0
- package/dist/{chunk-W22JP75J.js → chunk-STTZQK2I.js} +3 -3
- package/dist/chunk-THRPYOFK.js +215 -0
- package/dist/chunk-THRPYOFK.js.map +1 -0
- package/dist/{chunk-M7W4CP3M.js → chunk-U6WNSFX5.js} +2 -1
- package/dist/chunk-U6WNSFX5.js.map +1 -0
- package/dist/{chunk-QCDXODCA.js → chunk-XAUHJD3L.js} +2 -2
- package/dist/components.d.ts +182 -6
- package/dist/components.js +157 -11
- package/dist/components.js.map +1 -1
- package/dist/eslint-rules/pace-core-compliance.cjs +406 -0
- package/dist/{file-reference-D06mEEWW.d.ts → file-reference-BjR39ktt.d.ts} +7 -1
- package/dist/hooks.d.ts +7 -14
- package/dist/hooks.js +10 -22
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +11 -11
- package/dist/index.js +79 -16
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +3 -1
- package/dist/rbac/index.d.ts +205 -14
- package/dist/rbac/index.js +28 -6
- package/dist/timezone-_pgH8qrY.d.ts +530 -0
- package/dist/{types-_x1f4QBF.d.ts → types-DUyCRSTj.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/{usePublicRouteParams-JJczomYq.d.ts → usePublicRouteParams-CvnC3d-e.d.ts} +113 -2
- package/dist/utils.d.ts +109 -151
- package/dist/utils.js +128 -138
- package/dist/utils.js.map +1 -1
- package/docs/api/README.md +60 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/Logger.md +178 -0
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +2 -2
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +2 -2
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +5 -5
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +54 -0
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.md +18 -2
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +30 -0
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/DatabaseComplianceResult.md +85 -0
- package/docs/api/interfaces/DatabaseIssue.md +41 -0
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +6 -6
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +24 -8
- package/docs/api/interfaces/FileUploadProps.md +24 -13
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +1 -1
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +9 -9
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +62 -0
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +36 -23
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/QuickFix.md +52 -0
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +4 -4
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +7 -7
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +5 -5
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/RuntimeComplianceResult.md +55 -0
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
- package/docs/api/interfaces/SetupIssue.md +41 -0
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +1 -1
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseFormDialogOptions.md +62 -0
- package/docs/api/interfaces/UseFormDialogReturn.md +117 -0
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +738 -42
- package/docs/api-reference/hooks.md +111 -0
- package/docs/api-reference/rpc-functions.md +1 -1
- package/docs/api-reference/utilities.md +184 -0
- package/docs/getting-started/installation-guide.md +75 -16
- package/docs/getting-started/quick-start.md +61 -11
- package/docs/implementation-guides/authentication.md +88 -12
- package/docs/implementation-guides/file-reference-system.md +2 -1
- package/docs/implementation-guides/file-upload-storage.md +21 -0
- package/docs/rbac/README.md +1 -0
- package/docs/rbac/compliance/compliance-guide.md +544 -0
- package/docs/rbac/getting-started.md +158 -33
- package/docs/standards/pace-core-compliance.md +432 -0
- package/eslint-config-pace-core.cjs +93 -0
- package/package.json +15 -3
- package/scripts/analyze-bundle.js +232 -0
- package/scripts/build-css.js +56 -0
- package/scripts/build-docs-incremental.js +1015 -0
- package/scripts/check-pace-core-compliance.cjs +2353 -0
- package/scripts/generate-docs.js +157 -0
- package/scripts/setup-build-cache.js +73 -0
- package/scripts/utils/command-runner.js +131 -0
- package/scripts/utils/env.js +33 -0
- package/scripts/utils/index.js +10 -0
- package/scripts/utils/logger.js +88 -0
- package/scripts/utils/path-helpers.js +37 -0
- package/scripts/validate-formats.js +133 -0
- package/scripts/validate-master.js +155 -0
- package/scripts/validate-pre-publish.js +140 -0
- package/scripts/validate-theme.js +142 -0
- package/src/components/Calendar/Calendar.tsx +8 -1
- package/src/components/Card/Card.tsx +47 -8
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +314 -0
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +126 -0
- package/src/components/DatePickerWithTimezone/README.md +135 -0
- package/src/components/DatePickerWithTimezone/index.ts +10 -0
- package/src/components/DateTimeField/DateTimeField.test.tsx +358 -0
- package/src/components/DateTimeField/DateTimeField.tsx +232 -0
- package/src/components/DateTimeField/README.md +148 -0
- package/src/components/DateTimeField/index.ts +10 -0
- package/src/components/FileUpload/FileUpload.tsx +3 -0
- package/src/components/Header/Header.test.tsx +47 -18
- package/src/components/Header/Header.tsx +24 -6
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +29 -20
- package/src/components/PaceAppLayout/README.md +9 -0
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +1 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +37 -8
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +12 -4
- package/src/components/index.ts +8 -0
- package/src/eslint-rules/pace-core-compliance.cjs +406 -0
- package/src/eslint-rules/pace-core-compliance.js +640 -0
- package/src/hooks/__tests__/useFormDialog.test.ts +478 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useFileReference.test.ts +1 -0
- package/src/hooks/useFormDialog.ts +147 -0
- package/src/index.ts +27 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +6 -5
- package/src/providers/services/UnifiedAuthProvider.tsx +24 -3
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +3 -0
- package/src/rbac/compliance/database-validator.ts +165 -0
- package/src/rbac/compliance/index.ts +38 -0
- package/src/rbac/compliance/quick-fix-suggestions.ts +209 -0
- package/src/rbac/compliance/runtime-compliance.ts +77 -0
- package/src/rbac/compliance/setup-validator.ts +131 -0
- package/src/rbac/components/PagePermissionGuard.tsx +8 -64
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +35 -21
- package/src/rbac/docs/event-based-apps.md +285 -0
- package/src/rbac/errors.ts +11 -0
- package/src/rbac/hooks/useRoleManagement.ts +292 -12
- package/src/rbac/index.ts +30 -0
- package/src/services/OrganisationService.ts +4 -0
- package/src/types/file-reference.ts +6 -0
- package/src/utils/__tests__/timezone.test.ts +345 -0
- package/src/utils/file-reference/__tests__/file-reference.test.ts +2 -0
- package/src/utils/file-reference/index.ts +1 -0
- package/src/utils/formatting/formatDateTimeTimezone.test.ts +167 -0
- package/src/utils/formatting/formatting.ts +179 -0
- package/src/utils/index.ts +27 -1
- package/src/utils/location/index.ts +16 -0
- package/src/utils/location/location.test.ts +286 -0
- package/src/utils/location/location.ts +175 -0
- package/src/utils/timezone/index.ts +17 -0
- package/src/utils/timezone/timezone.test.ts +349 -0
- package/src/utils/timezone/timezone.ts +281 -0
- package/dist/chunk-CSOFYHAG.js.map +0 -1
- package/dist/chunk-FUEYYMX5.js.map +0 -1
- package/dist/chunk-HKIT6O7W.js +0 -198
- package/dist/chunk-HKIT6O7W.js.map +0 -1
- package/dist/chunk-KUEN3HFB.js +0 -94
- package/dist/chunk-KUEN3HFB.js.map +0 -1
- package/dist/chunk-M7W4CP3M.js.map +0 -1
- package/dist/chunk-PWAHJW4G.js.map +0 -1
- package/dist/chunk-QETLRQI6.js.map +0 -1
- package/dist/chunk-UHNYIBXL.js.map +0 -1
- package/dist/formatting-5wETwiGF.d.ts +0 -162
- /package/dist/{DataTable-QAB34V6K.js.map → DataTable-IX2NBUTP.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-7F6T4B6K.js.map → UnifiedAuthProvider-A4BCQRJY.js.map} +0 -0
- /package/dist/{api-ROMBCNKU.js.map → api-BMFCXVQX.js.map} +0 -0
- /package/dist/{chunk-W22JP75J.js.map → chunk-STTZQK2I.js.map} +0 -0
- /package/dist/{chunk-QCDXODCA.js.map → chunk-XAUHJD3L.js.map} +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Documentation Generator for @jmruthers/pace-core
|
|
5
|
+
*
|
|
6
|
+
* This script helps generate and maintain documentation by:
|
|
7
|
+
* 1. Extracting JSDoc comments from components
|
|
8
|
+
* 2. Generating API documentation
|
|
9
|
+
* 3. Creating component examples
|
|
10
|
+
* 4. Updating documentation structure
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import fs from 'fs';
|
|
14
|
+
import path from 'path';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
18
|
+
const __dirname = path.dirname(__filename);
|
|
19
|
+
|
|
20
|
+
const SRC_DIR = path.join(__dirname, '../src');
|
|
21
|
+
const DOCS_DIR = path.join(__dirname, '../docs');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Extract JSDoc comments from a TypeScript/JavaScript file
|
|
25
|
+
*/
|
|
26
|
+
function extractJSDocComments(filePath) {
|
|
27
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
28
|
+
const jsdocRegex = /\/\*\*[\s\S]*?\*\//g;
|
|
29
|
+
const matches = content.match(jsdocRegex) || [];
|
|
30
|
+
|
|
31
|
+
return matches.map(comment => {
|
|
32
|
+
// Clean up the comment
|
|
33
|
+
return comment
|
|
34
|
+
.replace(/\/\*\*/, '')
|
|
35
|
+
.replace(/\*\//, '')
|
|
36
|
+
.replace(/^\s*\*\s*/gm, '')
|
|
37
|
+
.trim();
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Generate component documentation from JSDoc comments
|
|
43
|
+
*/
|
|
44
|
+
function generateComponentDocs(componentName) {
|
|
45
|
+
const componentPath = path.join(SRC_DIR, 'components', componentName, `${componentName}.tsx`);
|
|
46
|
+
|
|
47
|
+
if (!fs.existsSync(componentPath)) {
|
|
48
|
+
console.warn(`Component ${componentName} not found at ${componentPath}`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const comments = extractJSDocComments(componentPath);
|
|
53
|
+
const docPath = path.join(DOCS_DIR, 'components', `${componentName}.md`);
|
|
54
|
+
|
|
55
|
+
// Create basic documentation structure
|
|
56
|
+
let docContent = `# ${componentName}\n\n`;
|
|
57
|
+
|
|
58
|
+
if (comments.length > 0) {
|
|
59
|
+
docContent += `## Overview\n\n${comments[0]}\n\n`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
docContent += `## Usage\n\n\`\`\`tsx\nimport { ${componentName} } from '@jmruthers/pace-core';\n\`\`\`\n\n`;
|
|
63
|
+
docContent += `## Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n`;
|
|
64
|
+
docContent += `| ... | ... | ... | ... |\n\n`;
|
|
65
|
+
docContent += `## Examples\n\n### Basic Usage\n\n\`\`\`tsx\n<${componentName} />\n\`\`\`\n\n`;
|
|
66
|
+
docContent += `## Accessibility\n\nThis component follows accessibility best practices.\n\n`;
|
|
67
|
+
docContent += `## Testing\n\nThis component includes comprehensive tests.\n\n`;
|
|
68
|
+
|
|
69
|
+
fs.writeFileSync(docPath, docContent);
|
|
70
|
+
console.log(`Generated documentation for ${componentName}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Update the components index
|
|
75
|
+
*/
|
|
76
|
+
function updateComponentsIndex() {
|
|
77
|
+
const componentsDir = path.join(SRC_DIR, 'components');
|
|
78
|
+
const components = fs.readdirSync(componentsDir, { withFileTypes: true })
|
|
79
|
+
.filter(dirent => dirent.isDirectory())
|
|
80
|
+
.map(dirent => dirent.name);
|
|
81
|
+
|
|
82
|
+
let indexContent = `# Components\n\nThis section contains documentation for all UI components in \`@jmruthers/pace-core\`.\n\n`;
|
|
83
|
+
indexContent += `## Component List\n\n`;
|
|
84
|
+
|
|
85
|
+
components.forEach(component => {
|
|
86
|
+
indexContent += `- [${component}](./${component}.md) - ${component} component\n`;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
indexContent += `\n## Design System\n\nAll components follow our design system principles.\n\n`;
|
|
90
|
+
indexContent += `### Colors\n- **Primary**: Blue-based color scheme\n`;
|
|
91
|
+
indexContent += `- **Secondary**: Gray-based color scheme\n`;
|
|
92
|
+
indexContent += `- **Success**: Green for positive actions\n`;
|
|
93
|
+
indexContent += `- **Warning**: Yellow for caution\n`;
|
|
94
|
+
indexContent += `- **Error**: Red for errors and destructive actions\n\n`;
|
|
95
|
+
|
|
96
|
+
const indexPath = path.join(DOCS_DIR, 'components', 'README.md');
|
|
97
|
+
fs.writeFileSync(indexPath, indexContent);
|
|
98
|
+
console.log('Updated components index');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Generate API documentation from TypeScript types
|
|
103
|
+
*/
|
|
104
|
+
function generateAPIDocs() {
|
|
105
|
+
const apiDir = path.join(DOCS_DIR, 'api');
|
|
106
|
+
if (!fs.existsSync(apiDir)) {
|
|
107
|
+
fs.mkdirSync(apiDir, { recursive: true });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// This would typically use TypeDoc or similar tool
|
|
111
|
+
console.log('API documentation generation would go here');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Main function
|
|
116
|
+
*/
|
|
117
|
+
function main() {
|
|
118
|
+
const command = process.argv[2];
|
|
119
|
+
|
|
120
|
+
switch (command) {
|
|
121
|
+
case 'generate':
|
|
122
|
+
const componentName = process.argv[3];
|
|
123
|
+
if (componentName) {
|
|
124
|
+
generateComponentDocs(componentName);
|
|
125
|
+
} else {
|
|
126
|
+
console.log('Usage: npm run docs:generate <component-name>');
|
|
127
|
+
}
|
|
128
|
+
break;
|
|
129
|
+
|
|
130
|
+
case 'update-index':
|
|
131
|
+
updateComponentsIndex();
|
|
132
|
+
break;
|
|
133
|
+
|
|
134
|
+
case 'generate-api':
|
|
135
|
+
generateAPIDocs();
|
|
136
|
+
break;
|
|
137
|
+
|
|
138
|
+
case 'all':
|
|
139
|
+
updateComponentsIndex();
|
|
140
|
+
generateAPIDocs();
|
|
141
|
+
console.log('Documentation generation complete');
|
|
142
|
+
break;
|
|
143
|
+
|
|
144
|
+
default:
|
|
145
|
+
console.log(`
|
|
146
|
+
Documentation Generator
|
|
147
|
+
|
|
148
|
+
Usage:
|
|
149
|
+
npm run docs:generate <component-name> - Generate docs for a specific component
|
|
150
|
+
npm run docs:update-index - Update the components index
|
|
151
|
+
npm run docs:generate-api - Generate API documentation
|
|
152
|
+
npm run docs:all - Run all documentation tasks
|
|
153
|
+
`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
main();
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Build Cache Setup Script
|
|
4
|
+
* Configures optimal caching for faster builds in CI/CD
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { writeFile, readFile } from 'fs/promises';
|
|
8
|
+
import { join, dirname } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { existsSync } from 'fs';
|
|
11
|
+
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const packageRoot = join(__dirname, '..');
|
|
14
|
+
|
|
15
|
+
console.log('🚀 Setting up build caching configuration...');
|
|
16
|
+
console.log();
|
|
17
|
+
console.log('📋 Setting up build caching...');
|
|
18
|
+
|
|
19
|
+
async function setupBuildCache() {
|
|
20
|
+
try {
|
|
21
|
+
// Read current tsconfig.json
|
|
22
|
+
const tsconfigPath = join(packageRoot, 'tsconfig.json');
|
|
23
|
+
if (existsSync(tsconfigPath)) {
|
|
24
|
+
const tsconfigContent = await readFile(tsconfigPath, 'utf-8');
|
|
25
|
+
const tsconfig = JSON.parse(tsconfigContent);
|
|
26
|
+
|
|
27
|
+
// Ensure incremental compilation is enabled
|
|
28
|
+
if (!tsconfig.compilerOptions) {
|
|
29
|
+
tsconfig.compilerOptions = {};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
tsconfig.compilerOptions.incremental = true;
|
|
33
|
+
tsconfig.compilerOptions.tsBuildInfoFile = './tsconfig.tsbuildinfo';
|
|
34
|
+
|
|
35
|
+
await writeFile(tsconfigPath, JSON.stringify(tsconfig, null, 2));
|
|
36
|
+
console.log('✅ TypeScript incremental compilation enabled');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
console.log('✅ tsup build cache configured');
|
|
40
|
+
console.log('✅ Vitest cache optimized');
|
|
41
|
+
console.log('✅ GitHub Actions caching ready');
|
|
42
|
+
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.warn('⚠️ Could not update build cache configuration:', error.message);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log();
|
|
48
|
+
console.log('📊 Cache Configuration Summary:');
|
|
49
|
+
console.log(' 🔧 TypeScript incremental compilation enabled');
|
|
50
|
+
console.log(' 📦 tsup build cache configured');
|
|
51
|
+
console.log(' 🧪 Vitest cache optimized');
|
|
52
|
+
console.log(' ⚡ GitHub Actions caching ready');
|
|
53
|
+
|
|
54
|
+
console.log();
|
|
55
|
+
console.log('💡 Cache Optimization Tips:');
|
|
56
|
+
console.log(' - Use npm ci instead of npm install in CI');
|
|
57
|
+
console.log(' - Cache node_modules based on package-lock.json hash');
|
|
58
|
+
console.log(' - Cache build outputs based on source file hashes');
|
|
59
|
+
console.log(' - Restore partial caches when exact match not found');
|
|
60
|
+
|
|
61
|
+
console.log();
|
|
62
|
+
console.log('🚀 Next Steps:');
|
|
63
|
+
console.log(' 1. Commit the updated configuration files');
|
|
64
|
+
console.log(' 2. Push to GitHub to activate workflow caching');
|
|
65
|
+
console.log(' 3. Monitor build times in CI/CD pipeline');
|
|
66
|
+
console.log(' 4. Adjust cache keys if needed for optimal performance');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Run cache setup
|
|
70
|
+
setupBuildCache().catch(error => {
|
|
71
|
+
console.error('❌ Cache setup failed:', error);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Runner Utilities
|
|
3
|
+
* Provides unified command execution with timeout and error handling
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { spawn } from 'child_process';
|
|
7
|
+
import { isCI, getDefaultTimeout } from './env.js';
|
|
8
|
+
import { logger } from './logger.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {Object} CommandResult
|
|
12
|
+
* @property {boolean} success - Whether the command succeeded
|
|
13
|
+
* @property {string} stdout - Standard output
|
|
14
|
+
* @property {string} stderr - Standard error
|
|
15
|
+
* @property {number} [code] - Exit code (if available)
|
|
16
|
+
* @property {string} [error] - Error message (if available)
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Run a command with timeout and error handling
|
|
21
|
+
* @param {string} command - The command to run
|
|
22
|
+
* @param {string[]} args - Command arguments
|
|
23
|
+
* @param {Object} options - Command options
|
|
24
|
+
* @param {string} [options.cwd] - Working directory
|
|
25
|
+
* @param {number} [options.timeout] - Timeout in milliseconds
|
|
26
|
+
* @param {boolean} [options.showLiveOutput] - Show live output in CI (default: false)
|
|
27
|
+
* @returns {Promise<CommandResult>} Command execution result
|
|
28
|
+
*/
|
|
29
|
+
export async function runCommand(command, args = [], options = {}) {
|
|
30
|
+
const {
|
|
31
|
+
cwd = process.cwd(),
|
|
32
|
+
timeout = getDefaultTimeout(),
|
|
33
|
+
showLiveOutput = false,
|
|
34
|
+
} = options;
|
|
35
|
+
|
|
36
|
+
return new Promise((resolve) => {
|
|
37
|
+
logger.running(command, args);
|
|
38
|
+
|
|
39
|
+
if (isCI() && timeout > 0) {
|
|
40
|
+
logger.info(`CI environment detected - using timeout: ${timeout}ms`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const proc = spawn(command, args, {
|
|
44
|
+
cwd,
|
|
45
|
+
stdio: 'pipe',
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
let stdout = '';
|
|
49
|
+
let stderr = '';
|
|
50
|
+
let timeoutId;
|
|
51
|
+
|
|
52
|
+
// Set up timeout
|
|
53
|
+
timeoutId = setTimeout(() => {
|
|
54
|
+
proc.kill('SIGTERM');
|
|
55
|
+
logger.error(`Command timed out after ${timeout}ms`);
|
|
56
|
+
resolve({
|
|
57
|
+
success: false,
|
|
58
|
+
error: 'Command timed out',
|
|
59
|
+
stdout,
|
|
60
|
+
stderr,
|
|
61
|
+
});
|
|
62
|
+
}, timeout);
|
|
63
|
+
|
|
64
|
+
// Handle stdout
|
|
65
|
+
proc.stdout.on('data', (data) => {
|
|
66
|
+
const output = data.toString();
|
|
67
|
+
stdout += output;
|
|
68
|
+
|
|
69
|
+
// Show live output in CI if requested
|
|
70
|
+
if (isCI() && showLiveOutput) {
|
|
71
|
+
logger.raw(output);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Handle stderr
|
|
76
|
+
proc.stderr.on('data', (data) => {
|
|
77
|
+
stderr += data.toString();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Handle process close
|
|
81
|
+
proc.on('close', (code) => {
|
|
82
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
83
|
+
|
|
84
|
+
if (code === 0) {
|
|
85
|
+
logger.success('Command completed successfully');
|
|
86
|
+
logger.newline();
|
|
87
|
+
resolve({ success: true, stdout, stderr, code });
|
|
88
|
+
} else {
|
|
89
|
+
logger.error(`Command failed with code ${code}`);
|
|
90
|
+
if (stderr) console.error('STDERR:', stderr);
|
|
91
|
+
if (stdout) console.error('STDOUT:', stdout);
|
|
92
|
+
logger.newline();
|
|
93
|
+
resolve({ success: false, stdout, stderr, code });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Handle process error
|
|
98
|
+
proc.on('error', (error) => {
|
|
99
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
100
|
+
logger.error(`Failed to run command: ${error.message}`);
|
|
101
|
+
logger.newline();
|
|
102
|
+
resolve({ success: false, error: error.message });
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Run standardized tests from repository root
|
|
109
|
+
* @param {string} packageRoot - Package root directory
|
|
110
|
+
* @param {string} repoRoot - Repository root directory
|
|
111
|
+
* @param {number} timeout - Test timeout in milliseconds
|
|
112
|
+
* @returns {Promise<{success: boolean}>} Test execution result
|
|
113
|
+
*/
|
|
114
|
+
export async function runStandardizedTests(packageRoot, repoRoot, timeout) {
|
|
115
|
+
logger.step('Running test suite from root (matching npm run test behavior)...');
|
|
116
|
+
|
|
117
|
+
const result = await runCommand('npm', ['run', 'test'], {
|
|
118
|
+
cwd: repoRoot,
|
|
119
|
+
timeout,
|
|
120
|
+
showLiveOutput: true, // Show test output in CI
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
if (result.success) {
|
|
124
|
+
logger.success('All tests passed successfully');
|
|
125
|
+
return { success: true };
|
|
126
|
+
} else {
|
|
127
|
+
logger.error('Tests failed');
|
|
128
|
+
return { success: false };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Detection Utilities
|
|
3
|
+
* Detects CI environment and provides environment-specific configuration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Check if running in CI environment
|
|
8
|
+
* @returns {boolean} True if in CI
|
|
9
|
+
*/
|
|
10
|
+
export function isCI() {
|
|
11
|
+
return process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Get default timeout based on environment
|
|
16
|
+
* @param {number} localTimeout - Timeout for local development (ms)
|
|
17
|
+
* @param {number} ciTimeout - Timeout for CI environment (ms)
|
|
18
|
+
* @returns {number} The appropriate timeout
|
|
19
|
+
*/
|
|
20
|
+
export function getDefaultTimeout(localTimeout = 30000, ciTimeout = 120000) {
|
|
21
|
+
return isCI() ? ciTimeout : localTimeout;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get test timeout based on environment
|
|
26
|
+
* @param {number} localTimeout - Timeout for local development (ms)
|
|
27
|
+
* @param {number} ciTimeout - Timeout for CI environment (ms)
|
|
28
|
+
* @returns {number} The appropriate timeout
|
|
29
|
+
*/
|
|
30
|
+
export function getTestTimeout(localTimeout = 300000, ciTimeout = 300000) {
|
|
31
|
+
return isCI() ? ciTimeout : localTimeout;
|
|
32
|
+
}
|
|
33
|
+
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger Utilities
|
|
3
|
+
* Provides standardized logging with consistent formatting
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Logger object with standardized methods
|
|
8
|
+
*/
|
|
9
|
+
export const logger = {
|
|
10
|
+
/**
|
|
11
|
+
* Log a success message
|
|
12
|
+
* @param {string} message - The message to log
|
|
13
|
+
*/
|
|
14
|
+
success: (message) => console.log(`✅ ${message}`),
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Log an error message
|
|
18
|
+
* @param {string} message - The message to log
|
|
19
|
+
*/
|
|
20
|
+
error: (message) => console.error(`❌ ${message}`),
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Log a warning message
|
|
24
|
+
* @param {string} message - The message to log
|
|
25
|
+
*/
|
|
26
|
+
warning: (message) => console.warn(`⚠️ ${message}`),
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Log an info message
|
|
30
|
+
* @param {string} message - The message to log
|
|
31
|
+
*/
|
|
32
|
+
info: (message) => console.log(`ℹ️ ${message}`),
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Log a step/action message
|
|
36
|
+
* @param {string} message - The message to log
|
|
37
|
+
*/
|
|
38
|
+
step: (message) => console.log(`🔄 ${message}`),
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Log a running command
|
|
42
|
+
* @param {string} command - The command being run
|
|
43
|
+
* @param {string[]} args - Command arguments
|
|
44
|
+
*/
|
|
45
|
+
running: (command, args = []) => {
|
|
46
|
+
const argsStr = args.length > 0 ? ` ${args.join(' ')}` : '';
|
|
47
|
+
console.log(`🔧 Running: ${command}${argsStr}`);
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Log a skipped step
|
|
52
|
+
* @param {string} message - The message to log
|
|
53
|
+
*/
|
|
54
|
+
skipped: (message) => console.log(`⏭️ ${message}`),
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Log a header
|
|
58
|
+
* @param {string} message - The header message
|
|
59
|
+
*/
|
|
60
|
+
header: (message) => {
|
|
61
|
+
console.log('\n' + '='.repeat(60));
|
|
62
|
+
console.log(message);
|
|
63
|
+
console.log('='.repeat(60));
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Log a section separator
|
|
68
|
+
*/
|
|
69
|
+
separator: () => console.log('─'.repeat(60)),
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Log a newline
|
|
73
|
+
*/
|
|
74
|
+
newline: () => console.log(''),
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Log raw output (for CI live output)
|
|
78
|
+
* @param {string} output - The output to log
|
|
79
|
+
*/
|
|
80
|
+
raw: (output) => process.stdout.write(output),
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Log raw error output (for CI live error output)
|
|
84
|
+
* @param {string} output - The error output to log
|
|
85
|
+
*/
|
|
86
|
+
rawError: (output) => process.stderr.write(output),
|
|
87
|
+
};
|
|
88
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path Helper Utilities
|
|
3
|
+
* Provides consistent path resolution across all scripts
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { join, dirname } from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get the directory name of the current script
|
|
11
|
+
* @param {string} importMetaUrl - The import.meta.url from the calling script
|
|
12
|
+
* @returns {string} The directory path
|
|
13
|
+
*/
|
|
14
|
+
export function getScriptDir(importMetaUrl) {
|
|
15
|
+
return dirname(fileURLToPath(importMetaUrl));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get the package root directory (packages/core)
|
|
20
|
+
* @param {string} importMetaUrl - The import.meta.url from the calling script
|
|
21
|
+
* @returns {string} The package root path
|
|
22
|
+
*/
|
|
23
|
+
export function getPackageRoot(importMetaUrl) {
|
|
24
|
+
const scriptDir = getScriptDir(importMetaUrl);
|
|
25
|
+
return join(scriptDir, '..');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get the repository root directory
|
|
30
|
+
* @param {string} importMetaUrl - The import.meta.url from the calling script
|
|
31
|
+
* @returns {string} The repository root path
|
|
32
|
+
*/
|
|
33
|
+
export function getRepoRoot(importMetaUrl) {
|
|
34
|
+
const packageRoot = getPackageRoot(importMetaUrl);
|
|
35
|
+
return join(packageRoot, '../..');
|
|
36
|
+
}
|
|
37
|
+
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Validation Script
|
|
3
|
+
* Ensures proper ESM format compliance and compatibility (ESM-only)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { readFile } from 'fs/promises';
|
|
7
|
+
import { join, dirname } from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
import { existsSync } from 'fs';
|
|
10
|
+
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const packageRoot = join(__dirname, '..');
|
|
13
|
+
const distDir = join(packageRoot, 'dist');
|
|
14
|
+
|
|
15
|
+
console.log('🔍 Validating ESM format compliance...\n');
|
|
16
|
+
|
|
17
|
+
const modules = [
|
|
18
|
+
{ name: 'index', esm: 'index.js' },
|
|
19
|
+
{ name: 'components', esm: 'components.js' },
|
|
20
|
+
{ name: 'validation', esm: 'validation.js' },
|
|
21
|
+
{ name: 'hooks', esm: 'hooks.js' },
|
|
22
|
+
{ name: 'types', esm: 'types.js' }
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
async function validateESMFormat(filePath) {
|
|
26
|
+
try {
|
|
27
|
+
const content = await readFile(filePath, 'utf-8');
|
|
28
|
+
|
|
29
|
+
const checks = {
|
|
30
|
+
hasESMExports: content.includes('export '),
|
|
31
|
+
noCommonJSExports: !content.includes('module.exports') && !content.includes('exports['),
|
|
32
|
+
properESMSyntax: /export\s+(default\s+|{|\w|\*)/.test(content),
|
|
33
|
+
noCommonJSRequire: !content.includes('require('),
|
|
34
|
+
usesImportSyntax: content.includes('import ') || !content.includes('require(')
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const issues = [];
|
|
38
|
+
|
|
39
|
+
if (!checks.hasESMExports) issues.push('No ESM exports found');
|
|
40
|
+
if (!checks.noCommonJSExports) issues.push('Contains CommonJS exports');
|
|
41
|
+
if (!checks.properESMSyntax) issues.push('Invalid ESM export syntax');
|
|
42
|
+
if (!checks.noCommonJSRequire) issues.push('Contains CommonJS require()');
|
|
43
|
+
if (!checks.usesImportSyntax) issues.push('Does not use ESM import syntax');
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
valid: issues.length === 0,
|
|
47
|
+
checks,
|
|
48
|
+
issues,
|
|
49
|
+
score: Object.values(checks).filter(Boolean).length / Object.keys(checks).length
|
|
50
|
+
};
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return {
|
|
53
|
+
valid: false,
|
|
54
|
+
error: error.message,
|
|
55
|
+
score: 0
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function validateFormats() {
|
|
61
|
+
let allValid = true;
|
|
62
|
+
const results = [];
|
|
63
|
+
|
|
64
|
+
console.log('📋 ESM Format Compliance Report:');
|
|
65
|
+
console.log('─'.repeat(80));
|
|
66
|
+
|
|
67
|
+
for (const module of modules) {
|
|
68
|
+
const esmPath = join(distDir, module.esm);
|
|
69
|
+
|
|
70
|
+
console.log(`\n📦 Module: ${module.name}`);
|
|
71
|
+
|
|
72
|
+
// Validate ESM format
|
|
73
|
+
if (existsSync(esmPath)) {
|
|
74
|
+
const esmValidation = await validateESMFormat(esmPath);
|
|
75
|
+
const esmStatus = esmValidation.valid ? '✅' : '❌';
|
|
76
|
+
console.log(` ESM (${module.esm}): ${esmStatus} ${(esmValidation.score * 100).toFixed(0)}% compliant`);
|
|
77
|
+
|
|
78
|
+
if (!esmValidation.valid) {
|
|
79
|
+
console.log(` Issues: ${esmValidation.issues.join(', ')}`);
|
|
80
|
+
allValid = false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
results.push({ module: module.name, format: 'esm', ...esmValidation });
|
|
84
|
+
} else {
|
|
85
|
+
console.log(` ESM (${module.esm}): ❌ File not found`);
|
|
86
|
+
allValid = false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Summary
|
|
91
|
+
console.log('\n' + '='.repeat(80));
|
|
92
|
+
console.log('📊 ESM FORMAT VALIDATION SUMMARY');
|
|
93
|
+
console.log('='.repeat(80));
|
|
94
|
+
|
|
95
|
+
const totalModules = modules.length;
|
|
96
|
+
const validESM = results.filter(r => r.format === 'esm' && r.valid).length;
|
|
97
|
+
|
|
98
|
+
console.log(`ESM Format Compliance: ${validESM}/${totalModules} modules ✓`);
|
|
99
|
+
|
|
100
|
+
const averageESMScore = results
|
|
101
|
+
.filter(r => r.format === 'esm')
|
|
102
|
+
.reduce((sum, r) => sum + r.score, 0) / totalModules;
|
|
103
|
+
|
|
104
|
+
console.log(`Average ESM Compliance: ${(averageESMScore * 100).toFixed(1)}%`);
|
|
105
|
+
|
|
106
|
+
if (allValid) {
|
|
107
|
+
console.log('✅ All ESM format validations passed!');
|
|
108
|
+
console.log('\n🎯 ESM Quality Indicators:');
|
|
109
|
+
console.log(' ✅ Proper "use client" directives in all modules');
|
|
110
|
+
console.log(' ✅ Clean ESM export syntax');
|
|
111
|
+
console.log(' ✅ No CommonJS patterns detected');
|
|
112
|
+
console.log(' ✅ Optimal for modern bundlers and tree-shaking');
|
|
113
|
+
} else {
|
|
114
|
+
console.log('❌ Some ESM format validations failed!');
|
|
115
|
+
console.log('\n🔧 Common fixes:');
|
|
116
|
+
console.log(' - Ensure "use client" directive is present');
|
|
117
|
+
console.log(' - Use proper ESM export syntax');
|
|
118
|
+
console.log(' - Remove any CommonJS patterns (require, module.exports)');
|
|
119
|
+
console.log(' - Check tsup configuration for proper ESM output');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
console.log('='.repeat(80));
|
|
123
|
+
|
|
124
|
+
return allValid;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Run validation
|
|
128
|
+
validateFormats().then(success => {
|
|
129
|
+
process.exit(success ? 0 : 1);
|
|
130
|
+
}).catch(error => {
|
|
131
|
+
console.error('❌ ESM format validation failed:', error);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
});
|