@atlaskit/platform-feature-flags
Advanced tools
Comparing version 0.0.8 to 0.0.9
# @atlaskit/platform-feature-flags | ||
## 0.0.9 | ||
### Patch Changes | ||
- [`0ba3b02365e`](https://bitbucket.org/atlassian/atlassian-frontend/commits/0ba3b02365e) - Fix postinstall hook and ship less dependencies | ||
## 0.0.8 | ||
@@ -4,0 +10,0 @@ |
{ | ||
"name": "@atlaskit/platform-feature-flags", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"sideEffects": false | ||
} |
{ | ||
"name": "@atlaskit/platform-feature-flags", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"sideEffects": false | ||
} |
{ | ||
"name": "@atlaskit/platform-feature-flags", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"sideEffects": false | ||
} |
/** AUTOGENERATED DO NOT EDIT **/ | ||
export declare type BooleanFeatureFlagType = "uip.popper.flex-team"; | ||
export type BooleanFeatureFlagType = "uip.popper.flex-team"; |
{ | ||
"name": "@atlaskit/platform-feature-flags", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"description": "DO NOT USE", | ||
@@ -8,3 +8,6 @@ "publishConfig": { | ||
}, | ||
"repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://bitbucket.org/atlassian/atlassian-frontend-mirror.git" | ||
}, | ||
"author": "Atlassian Pty Ltd", | ||
@@ -31,13 +34,20 @@ "license": "Apache-2.0", | ||
"devDependencies": { | ||
"@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1", | ||
"fast-glob": "^3.2.11" | ||
"@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1" | ||
}, | ||
"prettier": "@atlassian/atlassian-frontend-prettier-config-1.0.1", | ||
"scripts": { | ||
"generate": "ts-node ./scripts/generate-types.ts && yarn update-built-types", | ||
"postinstall": "yarn generate", | ||
"pr-pipeline:pre": "sh ./scripts/pr-pipeline-clean.sh && yarn update-built-types", | ||
"pr-pipeline:post": "ts-node ./scripts/generate-types.ts && yarn update-built-types", | ||
"update-built-types": "sh ./scripts/update-built-types.sh" | ||
} | ||
"generate": "./scripts/generate-types.sh", | ||
"postinstall": "npm run generate", | ||
"update-built-types": "./scripts/update-built-types.sh", | ||
"build-typegenerator": "tsc --esModuleInterop --skipLibCheck scripts/generate-types.ts --outDir dist", | ||
"internal-use-scripts-after-this": "echo noop", | ||
"ak-postbuild": "npm run build-typegenerator", | ||
"pr-pipeline:pre": "./scripts/pr-pipeline-clean.sh && yarn update-built-types", | ||
"pr-pipeline:post": "ts-node ./scripts/generate-types.ts && yarn update-built-types" | ||
}, | ||
"bugs": { | ||
"url": "https://bitbucket.org/atlassian/atlassian-frontend-mirror/issues" | ||
}, | ||
"homepage": "https://bitbucket.org/atlassian/atlassian-frontend-mirror#readme", | ||
"keywords": [] | ||
} |
import { main as generateTypes } from './generate-types'; | ||
import fastglob from 'fast-glob'; | ||
import { Dirent } from 'fs'; | ||
import fs from 'fs/promises'; | ||
let mockFastglobResult: string[] = []; | ||
jest.mock('fast-glob', () => | ||
jest.fn().mockImplementation(async () => mockFastglobResult), | ||
); | ||
let mockProcessCwdResult: string = ''; | ||
@@ -14,4 +10,8 @@ jest.mock('process', () => ({ | ||
let mockFsStatFileResult: { [key: string]: boolean }; | ||
let mockFsReadFileResults: { [key: string]: string }; | ||
let mockFsWriteFileArgs: [string, string] = ['', '']; | ||
let mockFsReadDirentResults: { | ||
[key: string]: Pick<Dirent, 'name' | 'isDirectory'>[]; | ||
}; | ||
@@ -23,3 +23,3 @@ jest.mock('fs/promises', () => ({ | ||
} | ||
throw new Error(); | ||
throw new Error(`${fileName} isn't mocked correctly`); | ||
}), | ||
@@ -29,6 +29,16 @@ writeFile: jest.fn().mockImplementation((...args) => { | ||
}), | ||
stat: jest.fn().mockImplementation((fileName) => { | ||
if (mockFsStatFileResult[fileName]) { | ||
return {}; | ||
} | ||
throw new Error(); | ||
}), | ||
readdir: jest.fn().mockImplementation((dir) => { | ||
if (mockFsReadDirentResults[dir]) { | ||
return mockFsReadDirentResults[dir]; | ||
} | ||
throw new Error(`${dir} isn't mocked correctly`); | ||
}), | ||
})); | ||
jest.mock('fast-glob', () => jest.fn().mockResolvedValue(mockFastglobResult)); | ||
describe('verify behaviour of dynamic type generation for feature flags', () => { | ||
@@ -41,4 +51,7 @@ beforeEach(() => { | ||
mockProcessCwdResult = ''; | ||
mockFastglobResult = ['package.json']; | ||
mockFsStatFileResult = { 'package.json': true }; | ||
mockFsReadFileResults = { 'package.json': '{}' }; | ||
mockFsReadDirentResults = { | ||
'.': [{ name: 'package.json', isDirectory: () => false }], | ||
}; | ||
await generateTypes(); | ||
@@ -55,3 +68,3 @@ expect(mockFsWriteFileArgs[1]).toMatchInlineSnapshot(` | ||
mockProcessCwdResult = ''; | ||
mockFastglobResult = ['package.json']; | ||
mockFsStatFileResult = { 'package.json': true }; | ||
mockFsReadFileResults = { | ||
@@ -61,2 +74,5 @@ 'package.json': | ||
}; | ||
mockFsReadDirentResults = { | ||
'.': [{ name: 'package.json', isDirectory: () => false }], | ||
}; | ||
await generateTypes(); | ||
@@ -73,3 +89,15 @@ expect(mockFsWriteFileArgs[1]).toMatchInlineSnapshot(` | ||
mockProcessCwdResult = ''; | ||
mockFastglobResult = ['package-1/package.json', 'package-2/package.json']; | ||
mockFsStatFileResult = { | ||
'package-1/package.json': true, | ||
'package-2/package.json': true, | ||
}; | ||
mockFsReadDirentResults = { | ||
'.': [ | ||
{ name: 'package.json', isDirectory: () => false }, | ||
{ name: 'package-1', isDirectory: () => true }, | ||
{ name: 'package-2', isDirectory: () => true }, | ||
], | ||
'package-1': [{ name: 'package.json', isDirectory: () => false }], | ||
'package-2': [{ name: 'package.json', isDirectory: () => false }], | ||
}; | ||
mockFsReadFileResults = { | ||
@@ -92,24 +120,17 @@ 'package.json': '{}', | ||
it('should generate valid type if multiple feature flags found', async () => { | ||
it('should throw error when merging flags declared as different types', async () => { | ||
mockProcessCwdResult = ''; | ||
mockFastglobResult = ['package-1/package.json', 'package-2/package.json']; | ||
mockFsReadFileResults = { | ||
'package.json': '{}', | ||
'package-1/package.json': | ||
'{"platform-feature-flags": {"package-1-flag": {"type": "boolean" } } }', | ||
'package-2/package.json': | ||
'{"platform-feature-flags": {"package-2-flag": {"type": "boolean" } } }', | ||
mockFsStatFileResult = { | ||
'package-1/package.json': true, | ||
'package-2/package.json': true, | ||
}; | ||
await generateTypes(); | ||
expect(mockFsWriteFileArgs[1]).toMatchInlineSnapshot(` | ||
"/** AUTOGENERATED DO NOT EDIT **/ | ||
export type BooleanFeatureFlagType = \\"package-1-flag\\" | \\"package-2-flag\\"; | ||
" | ||
`); | ||
}); | ||
it('should throw error when merging flags declared as different types', async () => { | ||
mockProcessCwdResult = ''; | ||
mockFastglobResult = ['package-1/package.json', 'package-2/package.json']; | ||
mockFsReadDirentResults = { | ||
'.': [ | ||
{ name: 'package.json', isDirectory: () => false }, | ||
{ name: 'package-1', isDirectory: () => true }, | ||
{ name: 'package-2', isDirectory: () => true }, | ||
], | ||
'package-1': [{ name: 'package.json', isDirectory: () => false }], | ||
'package-2': [{ name: 'package.json', isDirectory: () => false }], | ||
}; | ||
mockFsReadFileResults = { | ||
@@ -131,5 +152,13 @@ 'package.json': '{}', | ||
mockProcessCwdResult = ''; | ||
mockFastglobResult = ['package-1/package.json']; | ||
mockFsStatFileResult = { 'package-1/package.json': true }; | ||
mockFsReadDirentResults = { | ||
'.': [ | ||
{ name: 'package.json', isDirectory: () => false }, | ||
{ name: 'package-1', isDirectory: () => true }, | ||
], | ||
'package-1': [{ name: 'package.json', isDirectory: () => false }], | ||
}; | ||
mockFsReadFileResults = { | ||
'package.json': '{}', | ||
'package-1/package.json': | ||
@@ -146,5 +175,12 @@ '{"platform-feature-flags": {"test-flag": {"type": "string" } } }', | ||
mockProcessCwdResult = 'test/1/2/3/4'; | ||
mockFastglobResult = ['test/package.json', 'test/package-1/package.json']; | ||
mockFsReadDirentResults = { | ||
test: [ | ||
{ name: 'package.json', isDirectory: () => false }, | ||
{ name: 'package-1', isDirectory: () => true }, | ||
], | ||
'test/package-1': [{ name: 'package.json', isDirectory: () => false }], | ||
}; | ||
mockFsReadFileResults = { | ||
'test/package.json': '{}', | ||
'test/package-1/package.json': | ||
@@ -154,12 +190,17 @@ '{"platform-feature-flags": {"test-flag": {"type": "boolean" } } }', | ||
mockFsReadFileResults = { | ||
'test/package.json': '{}', | ||
'test/package-1/package.json': | ||
'{"platform-feature-flags": {"test-flag": {"type": "boolean" } } }', | ||
}; | ||
await generateTypes(); | ||
expect(fastglob).toHaveBeenCalledTimes(1); | ||
expect(fastglob).toHaveBeenCalledWith( | ||
['**/package.json'], | ||
expect.objectContaining({ | ||
cwd: 'test', | ||
}), | ||
); | ||
// fs.readdir only called from method that gets all package.json, there isn't one at the root so it should | ||
// only get package.json at 'test' and below | ||
expect(fs.readdir).toHaveBeenCalledWith('test', { withFileTypes: true }); | ||
expect(fs.readdir).not.toHaveBeenCalledWith('.', { withFileTypes: true }); | ||
}); | ||
}); | ||
export {}; |
/* eslint-disable no-console */ | ||
import fs from 'fs/promises'; | ||
import path from 'path'; | ||
import fastglob from 'fast-glob'; | ||
import process from 'process'; | ||
@@ -73,21 +72,42 @@ | ||
const exists = async (f: string): Promise<boolean> => { | ||
try { | ||
await fs.stat(f); | ||
return true; | ||
} catch { | ||
return false; | ||
} | ||
}; | ||
// return a big list of the content of all package.json's under the directory specified. | ||
const getAllPackageJson = async (rootDir: string): Promise<PackageJson[]> => { | ||
const packageJsonPaths = await fastglob(['**/package.json'], { | ||
ignore: ignoredDirs, | ||
cwd: rootDir, | ||
absolute: true, | ||
}); | ||
// Create a list to store the parsed package.json objects | ||
const packageJsonList: PackageJson[] = []; | ||
return ( | ||
await Promise.all( | ||
packageJsonPaths.map(async (packageJsonPath) => { | ||
const packageJsonContent = await fs.readFile(packageJsonPath, 'utf8'); | ||
try { | ||
const json: PackageJson = JSON.parse(packageJsonContent); | ||
return json; | ||
} catch (e) {} | ||
}), | ||
) | ||
).filter((json): json is PackageJson => json != null); | ||
// Read the root directory and get a list of all the subdirectories | ||
let subDirs: string[] = (await fs.readdir(rootDir, { withFileTypes: true })) | ||
.filter((dirent) => dirent.isDirectory()) | ||
.map((dirent) => dirent.name); | ||
// Read the package.json file in the root directory | ||
const packageJsonPath = path.join(rootDir, 'package.json'); | ||
if (await exists(packageJsonPath)) { | ||
const packageJsonContent = await fs.readFile(packageJsonPath, 'utf8'); | ||
try { | ||
const json: PackageJson = JSON.parse(packageJsonContent); | ||
packageJsonList.push(json); | ||
} catch (e) {} | ||
} | ||
// Recursively read the package.json files in the subdirectories | ||
packageJsonList.push( | ||
...( | ||
await Promise.all( | ||
subDirs | ||
.filter((dir) => !ignoredDirs.includes(dir)) | ||
.map((subDir) => getAllPackageJson(path.join(rootDir, subDir))), | ||
) | ||
).flat(), | ||
); | ||
return packageJsonList; | ||
}; | ||
@@ -170,3 +190,3 @@ | ||
await fs.writeFile('src/types.ts', fileContent); | ||
await fs.writeFile('types.generated.ts', fileContent); | ||
}; | ||
@@ -173,0 +193,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
45846
1
37
897
0
1