diff --git a/source/common/config/rush/pnpm-lock.yaml b/source/common/config/rush/pnpm-lock.yaml index c84b1a14..313ac5d1 100644 --- a/source/common/config/rush/pnpm-lock.yaml +++ b/source/common/config/rush/pnpm-lock.yaml @@ -2138,6 +2138,25 @@ importers: specifier: 4.2.4 version: 4.2.4 + ../../packages/libraries/core/version: + dependencies: + '@swc/core': + specifier: ~1.5.3 + version: 1.5.3 + '@types/node': + specifier: ^18.17.0 + version: 18.17.0 + devDependencies: + '@awssolutions/eslint-config-custom': + specifier: workspace:~0.0.0 + version: link:../../config/eslint-config-custom + ts-morph: + specifier: ~22.0.0 + version: 22.0.0 + typescript: + specifier: 4.2.4 + version: 4.2.4 + ../../packages/libraries/simulator/device-simulator-base: dependencies: aws-iot-device-sdk: @@ -10037,11 +10056,145 @@ packages: tslib: 2.6.1 dev: false + /@swc/core-darwin-arm64@1.5.3: + resolution: {integrity: sha512-kRmmV2XqWegzGXvJfVVOj10OXhLgaVOOBjaX3p3Aqg7Do5ksg+bY5wi1gAN/Eul7B08Oqf7GG7WJevjDQGWPOg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@swc/core-darwin-x64@1.5.3: + resolution: {integrity: sha512-EYs0+ovaRw6ZN9GBr2nIeC7gUXWA0q4RYR+Og3Vo0Qgv2Mt/XudF44A2lPK9X7M3JIfu6JjnxnTuvsK1Lqojfw==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@swc/core-linux-arm-gnueabihf@1.5.3: + resolution: {integrity: sha512-RBVUTidSf4wgPdv98VrgJ4rMzMDN/3LBWdT7l+R7mNFH+mtID7ZAhTON0o/m1HkECgAgi1xcbTOVAw1xgd5KLA==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@swc/core-linux-arm64-gnu@1.5.3: + resolution: {integrity: sha512-DCC6El3MiTYfv98CShxz/g2s4Pxn6tV0mldCQ0UdRqaN2ApUn7E+zTrqaj5bk7yII3A43WhE9Mr6wNPbXUeVyg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@swc/core-linux-arm64-musl@1.5.3: + resolution: {integrity: sha512-p04ysjYXEyaCGpJvwHm0T0nkPawXtdKBTThWnlh8M5jYULVNVA1YmC9azG2Avs1GDaLgBPVUgodmFYpdSupOYA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@swc/core-linux-x64-gnu@1.5.3: + resolution: {integrity: sha512-/l4KJu0xwYm6tcVSOvF8RbXrIeIHJAhWnKvuX4ZnYKFkON968kB8Ghx+1yqBQcZf36tMzSuZUC5xBUA9u66lGA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@swc/core-linux-x64-musl@1.5.3: + resolution: {integrity: sha512-54DmSnrTXq4fYEKNR0nFAImG3+FxsHlQ6Tol/v3l+rxmg2K0FeeDOpH7wTXeWhMGhFlGrLIyLSnA+SzabfoDIA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@swc/core-win32-arm64-msvc@1.5.3: + resolution: {integrity: sha512-piUMqoHNwDXChBfaaFIMzYgoxepfd8Ci1uXXNVEnuiRKz3FiIcNLmvXaBD7lKUwKcnGgVziH/CrndX6SldKQNQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@swc/core-win32-ia32-msvc@1.5.3: + resolution: {integrity: sha512-zV5utPYBUzYhBOomCByAjKAvfVBcOCJtnszx7Zlfz7SAv/cGm8D1QzPDCvv6jDhIlUtLj6KyL8JXeFr+f95Fjw==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@swc/core-win32-x64-msvc@1.5.3: + resolution: {integrity: sha512-QmUiXiPIV5gBADfDh8e2jKynEhyRC+dcKP/zF9y5KqDUErYzlhocLd68uYS4uIegP6AylYlmigHgcaktGEE9VQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@swc/core@1.5.3: + resolution: {integrity: sha512-pSEglypnBGLHBoBcv3aYS7IM2t2LRinubYMyP88UoFIcD2pear2CeB15CbjJ2IzuvERD0ZL/bthM7cDSR9g+aQ==} + engines: {node: '>=10'} + requiresBuild: true + peerDependencies: + '@swc/helpers': ^0.5.0 + peerDependenciesMeta: + '@swc/helpers': + optional: true + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.6 + optionalDependencies: + '@swc/core-darwin-arm64': 1.5.3 + '@swc/core-darwin-x64': 1.5.3 + '@swc/core-linux-arm-gnueabihf': 1.5.3 + '@swc/core-linux-arm64-gnu': 1.5.3 + '@swc/core-linux-arm64-musl': 1.5.3 + '@swc/core-linux-x64-gnu': 1.5.3 + '@swc/core-linux-x64-musl': 1.5.3 + '@swc/core-win32-arm64-msvc': 1.5.3 + '@swc/core-win32-ia32-msvc': 1.5.3 + '@swc/core-win32-x64-msvc': 1.5.3 + dev: false + + /@swc/counter@0.1.3: + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + dev: false + + /@swc/types@0.1.6: + resolution: {integrity: sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==} + dependencies: + '@swc/counter': 0.1.3 + dev: false + /@tootallnate/once@1.1.2: resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} dev: true + /@ts-morph/common@0.23.0: + resolution: {integrity: sha512-m7Lllj9n/S6sOkCkRftpM7L24uvmfXQFedlW/4hENcuJH1HHm9u5EgxZb9uVjQSCGrbBWBkOGgcTxNg36r6ywA==} + dependencies: + fast-glob: 3.3.2 + minimatch: 9.0.4 + mkdirp: 3.0.1 + path-browserify: 1.0.1 + dev: true + /@types/adm-zip@0.4.34: resolution: {integrity: sha512-8ToYLLAYhkRfcmmljrKi22gT2pqu7hGMDtORP1emwIEGmgUTZOsaDjzWFzW5N2frcFRz/50CWt4zA1CxJ73pmQ==} dependencies: @@ -10424,7 +10577,6 @@ packages: /@types/node@18.17.0: resolution: {integrity: sha512-GXZxEtOxYGFchyUzxvKI14iff9KZ2DI+A6a37o6EQevtg6uO9t+aUZKcaC1Te5Ng1OnLM7K9NVVj+FbecD9cJg==} - dev: true /@types/node@18.17.1: resolution: {integrity: sha512-xlR1jahfizdplZYRU59JlUx9uzF1ARa8jbhM11ccpCJya8kvos5jwdm2ZAgxSCwOl0fq21svP18EVwPBXMQudw==} @@ -12142,6 +12294,10 @@ packages: engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} dev: true + /code-block-writer@13.0.1: + resolution: {integrity: sha512-c5or4P6erEA69TxaxTNcHUNcIn+oyxSRTOWV+pSYF+z4epXqNvwvJ70XPGjPNgue83oAFAPBRQYwpAJ/Hpe/Sg==} + dev: true + /code-point-at@1.1.0: resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} engines: {node: '>=0.10.0'} @@ -13231,6 +13387,17 @@ packages: merge2: 1.4.1 micromatch: 4.0.5 + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + /fast-json-patch@3.1.1: resolution: {integrity: sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==} dev: true @@ -16337,6 +16504,13 @@ packages: dependencies: brace-expansion: 2.0.1 + /minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimist@1.2.5: resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} dev: false @@ -16391,6 +16565,12 @@ packages: engines: {node: '>=10'} hasBin: true + /mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + dev: true + /mnemonist@0.38.3: resolution: {integrity: sha512-2K9QYubXx/NAjv4VLq1d1Ly8pWNC5L3BrixtdkyTegXWJIqY+zLNDhhX/A+ZwWt70tB1S8H4BE8FLYEFyNoOBw==} dependencies: @@ -17082,6 +17262,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: true + /path-dirname@1.0.2: resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} @@ -18782,6 +18966,13 @@ packages: yargs-parser: 21.1.1 dev: true + /ts-morph@22.0.0: + resolution: {integrity: sha512-M9MqFGZREyeb5fTl6gNHKZLqBQA0TjA1lea+CR48R8EBTDuWrNqW6ccC5QvjNR4s6wDumD3LTCjOFSp9iwlzaw==} + dependencies: + '@ts-morph/common': 0.23.0 + code-block-writer: 13.0.1 + dev: true + /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} diff --git a/source/common/config/rush/repo-state.json b/source/common/config/rush/repo-state.json index 692ff774..e1ce270d 100644 --- a/source/common/config/rush/repo-state.json +++ b/source/common/config/rush/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "d8b7c902b74f2c02b6c151ecccf06d926715e682", + "pnpmShrinkwrapHash": "f85cc14f59c4c9b6abdd1cf80944d1105fcb45bf", "preferredVersionsHash": "14c05a7722342014cec64c4bef7d9bed0d0b7b7f" } diff --git a/source/packages/libraries/core/version/.eslintrc.js b/source/packages/libraries/core/version/.eslintrc.js new file mode 100644 index 00000000..bff573d0 --- /dev/null +++ b/source/packages/libraries/core/version/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: ["@awssolutions/eslint-config-custom"], +}; \ No newline at end of file diff --git a/source/packages/libraries/core/version/package.json b/source/packages/libraries/core/version/package.json new file mode 100644 index 00000000..5f071019 --- /dev/null +++ b/source/packages/libraries/core/version/package.json @@ -0,0 +1,25 @@ +{ + "name": "@awssolutions/cdf-version", + "version": "0.0.0", + "description": "", + "main": "dist/index.js", + "module": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "clean": "npx shx rm -rf dist *.tsbuildinfo .rush .nyc_output *.log", + "lint": "npx eslint . --ext '.ts'", + "build": "npx ts-node --swc scripts/compile.ts", + "test": "rushx lint && jest --silent --passWithNoTests --maxWorkers=$JEST_MAX_WORKERS" + }, + "devDependencies": { + "@awssolutions/eslint-config-custom": "workspace:~0.0.0", + "@types/node": "^18.17.0", + "typescript": "4.2.4", + "ts-morph": "~22.0.0" + }, + "license": "ISC", + "dependencies": { + "@types/node": "^18.17.0", + "@swc/core": "~1.5.3" + } +} diff --git a/source/packages/libraries/core/version/scripts/compile.ts b/source/packages/libraries/core/version/scripts/compile.ts new file mode 100644 index 00000000..4174ba05 --- /dev/null +++ b/source/packages/libraries/core/version/scripts/compile.ts @@ -0,0 +1,73 @@ +import fs from 'fs'; +import readline from 'readline'; +import { Project } from 'ts-morph'; + +/** + * This function extract the version number from the version policies file, + * source/common/config/rush/version-policies.json, managed by rush. + * + * This JSON file contains comments, therefore regular "import" statement + * won't work. So we are reading the file line by line to get the external + * version number. + * + * The errors thrown from here will ONLY happen in build time. + * + * @returns version number string in SemVer format + */ +async function extractVersion(): Promise { + const versionPoliciesReadStream = fs.createReadStream( + '../../../../common/config/rush/version-policies.json' + ); + const rl = readline.createInterface({ + input: versionPoliciesReadStream, + crlfDelay: Infinity, + }); + + // NodeJS's readline interface doesn't support moving "only" one line. + // if the for-loop breaks, we won't be able to get the line we need. + // So we need to know what the "previous" line is to stop and get the + // "current" line that contains the version number + let previousLine: string = ''; + let versionLine: string | undefined = undefined; + for await (const line of rl) { + if (previousLine.includes('"policyName": "external",')) { + versionLine = line; + break; + } + + previousLine = line; + } + + if (!versionLine?.includes('"version"')) { + throw new Error('cdf-version: fail to capture version line.'); + } + + // https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string + const versionRegex = + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?/; + const version = versionLine.match(versionRegex); + + if (!version) { + throw new Error( + `cdf-version: fail to extract version number with regex, captured version line: ${versionLine}` + ); + } + + return version[0]; +} + +async function compile(): Promise { + const emittingProject = new Project({ + tsConfigFilePath: 'tsconfig.json', + }); + const version = await extractVersion(); + + const versionFile = emittingProject.getSourceFileOrThrow('src/version.ts'); + versionFile.replaceWithText((writer) => { + writer.writeLine(`export const version = ${JSON.stringify(version)}`); + }); + + await emittingProject.emit(); +} + +compile(); diff --git a/source/packages/libraries/core/version/src/index.ts b/source/packages/libraries/core/version/src/index.ts new file mode 100644 index 00000000..70fe043a --- /dev/null +++ b/source/packages/libraries/core/version/src/index.ts @@ -0,0 +1 @@ +export * from './version'; diff --git a/source/packages/libraries/core/version/src/version.ts b/source/packages/libraries/core/version/src/version.ts new file mode 100644 index 00000000..2234e8cf --- /dev/null +++ b/source/packages/libraries/core/version/src/version.ts @@ -0,0 +1,2 @@ +// Do not modify this file. The contents of this file are replaced during compilation. +export {}; diff --git a/source/packages/libraries/core/version/tsconfig.json b/source/packages/libraries/core/version/tsconfig.json new file mode 100644 index 00000000..6267edc7 --- /dev/null +++ b/source/packages/libraries/core/version/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.libraries.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + }, + "references": [], + "include": ["src"], + "exclude": ["node_modules", "dist"] +} diff --git a/source/rush.json b/source/rush.json index 111b6490..bc69d9fe 100644 --- a/source/rush.json +++ b/source/rush.json @@ -140,12 +140,18 @@ "reviewCategory": "library", "versionPolicyName": "external" }, + { + "packageName": "@awssolutions/cdf-version", + "projectFolder": "packages/libraries/core/version", + "reviewCategory": "library", + "versionPolicyName": "internal" + }, { "packageName": "@awssolutions/eslint-config-custom", "projectFolder": "packages/libraries/config/eslint-config-custom", "reviewCategory": "library", "versionPolicyName": "internal" - }, + }, { "packageName": "@awssolutions/cdf-environment-sanitizer", "projectFolder": "packages/libraries/core/environment-sanitizer",