chrome-types-helpers
Advanced tools
Comparing version 0.1.0-beta4 to 0.1.0-beta5
@@ -46,2 +46,5 @@ /** | ||
/** @type {types.ApiVersionData} */ | ||
#versionData = {}; | ||
/** | ||
@@ -52,5 +55,12 @@ * Process all raw feature files, seen as a number of top-level dictionaries. Takes ownership of | ||
* @param {types.RawFeatureFile} source | ||
* @param {types.ApiVersionData} apiVersionData | ||
*/ | ||
constructor(source) { | ||
constructor(source, apiVersionData) { | ||
this.#source = processFeatures(source); | ||
for (const key in apiVersionData) { | ||
if (key.startsWith('chrome.')) { | ||
this.#versionData[`api:${key.substr(7)}`] = apiVersionData[key]; | ||
} | ||
} | ||
} | ||
@@ -132,10 +142,5 @@ | ||
* @param {string} path | ||
* @param {Partial<types.Feature>?} parentFeature | ||
* @return {Partial<types.Feature>?} | ||
*/ | ||
query(path, parentFeature = {}) { | ||
if (parentFeature === null) { | ||
return null; | ||
} | ||
query(path) { | ||
const dependencies = [path]; | ||
@@ -180,2 +185,21 @@ const seenDependencies = new Set(dependencies); | ||
/** @type {types.VersionData=} */ | ||
const versionData = this.#versionData[path]; | ||
if (versionData) { | ||
selfFeature.availableFromVersion = versionData.low; | ||
if (versionData.deprecated !== undefined) { | ||
selfFeature.deprecatedSinceVersion = versionData.deprecated; | ||
} | ||
} else { | ||
// HACK: We don't report that 'return' is old, and declarative event listener stuff. | ||
const skipUnknownVersion = | ||
path.endsWith('.return') || | ||
path.endsWith('.instanceType') || | ||
path.endsWith('InstanceType'); | ||
if (!skipUnknownVersion) { | ||
// console.warn('unknown version', path); | ||
selfFeature.unknownVersion = true; | ||
} | ||
} | ||
for (const f of rawFeatures) { | ||
@@ -207,20 +231,25 @@ if (f.channel && channelOrder(f.channel) > channelOrder(selfFeature.supportedInChannel)) { | ||
/** @type {Partial<types.Feature>} */ | ||
const out = {}; | ||
return selfFeature; | ||
} | ||
} | ||
const allKeys = new Set([...Object.keys(parentFeature), ...Object.keys(selfFeature)]); | ||
allKeys.delete('permissions'); | ||
for (const key of allKeys) { | ||
if (parentFeature[key] !== selfFeature[key]) { | ||
out[key] = selfFeature[key]; | ||
} | ||
export function sparseFeature(selfFeature, parentFeature) { | ||
/** @type {Partial<types.Feature>} */ | ||
const out = {}; | ||
const allKeys = new Set([...Object.keys(parentFeature), ...Object.keys(selfFeature)]); | ||
allKeys.delete('permissions'); | ||
for (const key of allKeys) { | ||
if (selfFeature[key] && parentFeature[key] !== selfFeature[key]) { | ||
out[key] = selfFeature[key]; | ||
} | ||
} | ||
// Compare permissions as a list. | ||
const permissions = [...selfPermissions].filter((p) => !parentFeature.permissions?.includes(p)); | ||
out.permissions = permissions.length ? permissions : undefined; | ||
// Compare permissions as a list. | ||
const permissions = [...(selfFeature.permissions ?? [])].filter((p) => !parentFeature.permissions?.includes(p)); | ||
out.permissions = permissions.length ? permissions : undefined; | ||
return out; | ||
} | ||
return out; | ||
} | ||
@@ -335,3 +364,3 @@ | ||
return !parts.some((part) => { | ||
return part.endsWith('Private') || part.endsWith('Internal') || part === 'idltest'; | ||
return part.endsWith('Private') || part.endsWith('Internal') || part === 'api:idltest' || part === 'api:test'; | ||
}); | ||
@@ -338,0 +367,0 @@ } |
41
main.js
@@ -29,3 +29,3 @@ /** | ||
import { buildLimit } from './lib/limit.js'; | ||
import { cache } from './lib/source/cache.js'; | ||
import { cache, networkFetcher } from './lib/source/cache.js'; | ||
@@ -58,2 +58,5 @@ // @ts-ignore | ||
const defaultVersionData = 'https://unpkg.com/chrome-types@latest/version-data.json'; | ||
const featureFileMatch = /^_(\w+)_features.json$/; | ||
@@ -65,6 +68,11 @@ | ||
* | ||
* @param {string} revision | ||
* @param {Partial<types.MainOptions>} options | ||
* @return {Promise<types.MainResult>} | ||
*/ | ||
export async function prepareNamespaces(revision = defaultRevision) { | ||
export async function prepareNamespaces(options = {}) { | ||
const o = /** @type {types.MainOptions} */ (Object.assign({ | ||
revision: defaultRevision, | ||
versionData: defaultVersionData, | ||
}, options)); | ||
const tmpobj = tmp.dirSync(); | ||
@@ -79,6 +87,14 @@ const workPath = tmpobj.name; | ||
/** @type {types.ApiVersionData} */ | ||
let versionData; | ||
try { | ||
await fetchAllTo(workPath, definitionPaths, revision); | ||
await fetchAllTo(workPath, toolsPaths, revision); | ||
const defitionsPromise = fetchAllTo(workPath, definitionPaths, o.revision); | ||
const toolsPromise = fetchAllTo(workPath, toolsPaths, o.revision); | ||
const versionDataPromise = fetchVersionData(o.versionData); | ||
await defitionsPromise; | ||
await toolsPromise; | ||
versionData = await versionDataPromise; | ||
const allFiles = []; | ||
@@ -146,3 +162,3 @@ for (const p of definitionPaths) { | ||
const f = new Features(features); | ||
const f = new Features(features, versionData); | ||
const p = new parser.JSONSchemaParser(f, allNamespaceNames); | ||
@@ -166,1 +182,14 @@ | ||
} | ||
/** | ||
* @param {string} from probably a URL for now | ||
* @return {Promise<types.ApiVersionData>} | ||
*/ | ||
export async function fetchVersionData(from) { | ||
const raw = await cache(from, networkFetcher(from)); | ||
const json = JSON.parse(raw.toString('utf-8')); | ||
const {symbols} = json; | ||
return symbols; | ||
} | ||
@@ -5,3 +5,3 @@ { | ||
"license": "Apache-2.0", | ||
"version": "0.1.0-beta4", | ||
"version": "0.1.0-beta5", | ||
"type": "module", | ||
@@ -8,0 +8,0 @@ "dependencies": { |
@@ -21,3 +21,3 @@ /** | ||
import { propertyOverride } from './override.js'; | ||
import { Features, parentName } from './lib/features/helpers.js'; | ||
import { Features, parentName, sparseFeature } from './lib/features/helpers.js'; | ||
import { buildNamespaceAwareMarkdownRewrite } from './lib/comment.js'; | ||
@@ -171,8 +171,8 @@ | ||
* @param {types.RawType} raw | ||
* @param {string=} fallbackName | ||
* @param {string=} overrideName | ||
* @param {string=} fallbackType | ||
* @return {model.Property} | ||
*/ | ||
#parseProperty = (path, raw, fallbackName, fallbackType) => { | ||
const name = raw.name ?? raw.id ?? fallbackName; | ||
#parseProperty = (path, raw, overrideName, fallbackType) => { | ||
const name = overrideName ?? raw.name ?? raw.id; | ||
if (name === undefined) { | ||
@@ -494,2 +494,5 @@ throw new Error(`could not parse property, no name`); | ||
/** @type {{[path: string]: Partial<types.Feature>}} */ | ||
const canonicalFeatures = {}; | ||
const namespaceFeature = this.#features.query(`api:${namespace.name}`); | ||
@@ -500,2 +503,3 @@ if (!namespaceFeature) { | ||
namespace.feature = namespaceFeature; | ||
canonicalFeatures[namespace.name] = namespaceFeature; | ||
@@ -507,27 +511,28 @@ // Augment or hide every property within this namespace. | ||
/** | ||
* @param {string} path | ||
* @return {Partial<types.Feature>?} | ||
*/ | ||
const parentFeature = (path) => { | ||
for (const path of byPathKeys) { | ||
const parentPath = parentName(path); | ||
if (parentPath === namespace.name) { | ||
return namespace.feature; | ||
const node = byPath[path]; | ||
if (node.nodoc || byPath[parentPath]?.nodoc) { | ||
node.nodoc = true; | ||
continue; // don't bother looking up | ||
} | ||
const node = byPath[parentPath]; | ||
if (!node || node.nodoc) { | ||
return null; | ||
// Find the canonical parent feature, and bail if it does not exist. | ||
const parentFeature = canonicalFeatures[parentPath]; | ||
if (!parentFeature) { | ||
node.nodoc = true; | ||
continue; | ||
} | ||
return node.feature; | ||
}; | ||
for (const path of byPathKeys) { | ||
const pathFeature = this.#features.query(`api:${path}`, parentFeature(path)); | ||
const node = byPath[path]; | ||
if (!pathFeature) { | ||
// Find our own feature. If it does not exist then bail. | ||
const selfFeature = this.#features.query(`api:${path}`); | ||
if (!selfFeature) { | ||
node.nodoc = true; | ||
} else { | ||
// This is a valid feature, so set its feature information to the partial. | ||
node.feature = pathFeature; | ||
continue; | ||
} | ||
// This is a valid feature, so set its feature information to the sparse partial. | ||
canonicalFeatures[path] = selfFeature; | ||
node.feature = sparseFeature(selfFeature, parentFeature); | ||
} | ||
@@ -534,0 +539,0 @@ |
@@ -22,3 +22,3 @@ /** | ||
*/ | ||
export function prepareNamespaces(revision: string = 'main'): Promise<MainResult> | ||
export function prepareNamespaces(options?: MainOptions): Promise<MainResult> | ||
@@ -35,2 +35,8 @@ | ||
export interface MainOptions { | ||
revision: string, | ||
versionData: string, | ||
}; | ||
export type RawTypeType = | ||
@@ -134,2 +140,12 @@ 'array' | 'any' | 'int64' | 'binary' | 'boolean' | 'integer' | 'double' | 'number' | 'string' | 'object' | 'function'; | ||
export interface VersionData { | ||
low: number, | ||
release: string, | ||
deprecated?: number, | ||
} | ||
export type ApiVersionData = {[name: string]: VersionData}; | ||
/** | ||
@@ -148,4 +164,4 @@ * Describes a simplified feature within our codebase. This should be used as Partial<Feature>. | ||
// These are not yet set. | ||
availableFromVersion: 0; | ||
deprecatedSinceVersion: 0; | ||
availableFromVersion: number; | ||
deprecatedSinceVersion: number; | ||
unknownVersion: true; | ||
@@ -152,0 +168,0 @@ } |
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
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
165903
4953
0