@travetto/manifest 4.0.0-rc.0 → 4.0.0-rc.2

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.
@@ -1,36 +1,11 @@
1
+ import { existsSync } from 'node:fs';
2
+
1
3
  import { ManifestModuleUtil } from './module';
2
4
  import { path } from './path';
3
-
4
- import {
5
- ManifestModule, ManifestModuleCore, ManifestModuleFile,
6
- ManifestModuleFileType, ManifestModuleFolderType, ManifestModuleRole, ManifestRoot
7
- } from './types';
8
-
9
5
  import { ManifestUtil } from './util';
10
6
 
11
- export type FindConfig = {
12
- folder?: (folder: ManifestModuleFolderType) => boolean;
13
- module?: (module: IndexedModule) => boolean;
14
- file?: (file: IndexedFile) => boolean;
15
- sourceOnly?: boolean;
16
- };
17
-
18
- export type IndexedFile = {
19
- id: string;
20
- import: string;
21
- module: string;
22
- sourceFile: string;
23
- outputFile: string;
24
- relativeFile: string;
25
- role: ManifestModuleRole;
26
- type: ManifestModuleFileType;
27
- };
28
-
29
- export type IndexedModule = ManifestModuleCore & {
30
- sourcePath: string;
31
- outputPath: string;
32
- files: Record<ManifestModuleFolderType, IndexedFile[]>;
33
- };
7
+ import type { ManifestModuleFolderType } from './types/common';
8
+ import type { ManifestModule, ManifestRoot, ManifestModuleFile, IndexedModule, IndexedFile, FindConfig } from './types/manifest';
34
9
 
35
10
  const TypedObject: {
36
11
  keys<T = unknown, K extends keyof T = keyof T>(o: T): K[];
@@ -43,7 +18,7 @@ const TypedObject: {
43
18
  */
44
19
  export class ManifestIndex {
45
20
 
46
- #manifestFile: string;
21
+ #arbitraryLookup?: (parts: string[]) => ManifestModule | undefined;
47
22
  #manifest: ManifestRoot;
48
23
  #modules: IndexedModule[];
49
24
  #modulesByName: Record<string, IndexedModule> = {};
@@ -69,14 +44,8 @@ export class ManifestIndex {
69
44
  return this.#outputRoot;
70
45
  }
71
46
 
72
- get manifestFile(): string {
73
- return this.#manifestFile;
74
- }
75
-
76
47
  init(manifestInput: string): void {
77
- const { manifest, file } = ManifestUtil.readManifestSync(manifestInput);
78
- this.#manifest = manifest;
79
- this.#manifestFile = file;
48
+ this.#manifest = ManifestUtil.readManifestSync(manifestInput);
80
49
  this.#outputRoot = path.resolve(this.#manifest.workspace.path, this.#manifest.build.outputFolder);
81
50
  this.#index();
82
51
  }
@@ -104,12 +73,14 @@ export class ManifestIndex {
104
73
  this.#outputToEntry.clear();
105
74
  this.#importToEntry.clear();
106
75
  this.#sourceToEntry.clear();
76
+ this.#arbitraryLookup = undefined;
107
77
 
108
78
  this.#modules = Object.values(this.#manifest.modules)
109
79
  .map(m => ({
110
80
  ...m,
111
81
  outputPath: this.#resolveOutput(m.outputFolder),
112
82
  sourcePath: path.resolve(this.#manifest.workspace.path, m.sourceFolder),
83
+ children: new Set(),
113
84
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
114
85
  files: Object.fromEntries(
115
86
  Object.entries(m.files).map(([folder, files]) => [folder, this.#moduleFiles(m, files ?? [])])
@@ -128,6 +99,13 @@ export class ManifestIndex {
128
99
  }
129
100
  this.#modulesByName = Object.fromEntries(this.#modules.map(x => [x.name, x]));
130
101
  this.#modulesByFolder = Object.fromEntries(this.#modules.map(x => [x.sourceFolder, x]));
102
+
103
+ // Store child information
104
+ for (const mod of this.#modules) {
105
+ for (const p of mod.parents) {
106
+ this.#modulesByName[p]?.children.add(mod.name);
107
+ }
108
+ }
131
109
  }
132
110
 
133
111
  /**
@@ -138,11 +116,11 @@ export class ManifestIndex {
138
116
  }
139
117
 
140
118
  /**
141
- * Get all local modules
119
+ * Get all workspace modules
142
120
  * @returns
143
121
  */
144
- getLocalModules(): IndexedModule[] {
145
- return this.#modules.filter(x => x.local);
122
+ getWorkspaceModules(): IndexedModule[] {
123
+ return this.#modules.filter(x => x.workspace);
146
124
  }
147
125
 
148
126
  /**
@@ -237,12 +215,9 @@ export class ManifestIndex {
237
215
  /**
238
216
  * Build module list from an expression list (e.g. `@travetto/rest,-@travetto/log)
239
217
  */
240
- getModuleList(mode: 'local' | 'all', exprList: string = ''): Set<string> {
218
+ getModuleList(mode: 'workspace' | 'all', exprList: string = ''): Set<string> {
241
219
  const allMods = Object.keys(this.#manifest.modules);
242
- const active = new Set<string>(
243
- mode === 'local' ? this.getLocalModules().map(x => x.name) :
244
- (mode === 'all' ? allMods : [])
245
- );
220
+ const active = new Set<string>(mode === 'workspace' ? this.getWorkspaceModules().map(x => x.name) : allMods);
246
221
 
247
222
  for (const expr of exprList.split(/\s*,\s*/g)) {
248
223
  const [, neg, mod] = expr.match(/(-|[+])?([^+\- ]+)$/) ?? [];
@@ -257,21 +232,38 @@ export class ManifestIndex {
257
232
  }
258
233
 
259
234
  /**
260
- * Get all modules (transitively) that depend on this module
235
+ * Get all modules, parents or children, (transitively) of the provided root, in a DFS fashion
261
236
  */
262
- getDependentModules(root: IndexedModule): Set<IndexedModule> {
237
+ getDependentModules(root: IndexedModule | string, field: 'parents' | 'children'): IndexedModule[] {
263
238
  const seen = new Set<string>();
264
- const out = new Set<IndexedModule>();
265
- const toProcess = [root.name];
239
+ const out: IndexedModule[] = [];
240
+ const toProcess = [typeof root === 'string' ? root : root.name];
266
241
  while (toProcess.length) {
267
242
  const next = toProcess.shift()!;
268
- if (seen.has(next)) {
269
- continue;
243
+ if (!seen.has(next)) {
244
+ seen.add(next);
245
+ const mod = this.getModule(next)!;
246
+ toProcess.push(...mod[field]);
247
+ if (next !== this.#manifest.main.name) { // Do not include self
248
+ out.push(mod);
249
+ }
270
250
  }
271
- const mod = this.getModule(next)!;
272
- toProcess.push(...mod.parents);
273
- out.add(mod);
274
251
  }
275
252
  return out;
276
253
  }
254
+
255
+ /**
256
+ * Find the module for an arbitrary source file, if it falls under a given workspace module
257
+ */
258
+ findModuleForArbitraryFile(file: string): ManifestModule | undefined {
259
+ const base = this.#manifest.workspace.path;
260
+ const lookup = this.#arbitraryLookup ??= ManifestUtil.lookupTrie(
261
+ Object.values(this.#manifest.modules),
262
+ x => x.sourceFolder.split('/'),
263
+ sub =>
264
+ !existsSync(path.resolve(base, ...sub, 'package.json')) &&
265
+ !existsSync(path.resolve(base, ...sub, '.git'))
266
+ );
267
+ return lookup(file.replace(`${base}/`, '').split('/'));
268
+ }
277
269
  }
package/src/module.ts CHANGED
@@ -1,14 +1,11 @@
1
1
  import fs from 'node:fs/promises';
2
2
 
3
3
  import { path } from './path';
4
- import {
5
- ManifestContext,
6
- ManifestModule, ManifestModuleFile, ManifestModuleFileType,
7
- ManifestModuleFolderType,
8
- ManifestModuleRole
9
- } from './types';
10
- import { ModuleDep, ModuleDependencyVisitor } from './dependencies';
11
- import { PackageUtil } from './package';
4
+ import { PackageModuleVisitor } from './dependencies';
5
+
6
+ import type { ManifestModuleFileType, ManifestModuleRole, ManifestModuleFolderType } from './types/common';
7
+ import type { ManifestModuleFile, ManifestModule, PackageModule } from './types/manifest';
8
+ import type { ManifestContext } from './types/context';
12
9
 
13
10
  const EXT_MAPPING: Record<string, ManifestModuleFileType> = {
14
11
  '.js': 'js',
@@ -47,9 +44,10 @@ export class ManifestModuleUtil {
47
44
  /**
48
45
  * Simple file scanning
49
46
  */
50
- static async scanFolder(folder: string, mainLike = false): Promise<string[]> {
51
- if (!mainLike && folder in this.#scanCache) {
52
- return this.#scanCache[folder];
47
+ static async scanFolder(folder: string, full = false): Promise<string[]> {
48
+ const key = `${folder}|${full}`;
49
+ if (key in this.#scanCache) {
50
+ return this.#scanCache[key];
53
51
  }
54
52
 
55
53
  if (!await fs.stat(folder).catch(() => false)) {
@@ -73,7 +71,7 @@ export class ManifestModuleUtil {
73
71
  }
74
72
 
75
73
  for (const sub of await fs.readdir(top)) {
76
- const valid = !sub.startsWith('.') && (depth > 0 || mainLike);
74
+ const valid = !sub.startsWith('.') && (depth > 0 || full);
77
75
  const stat = await fs.stat(`${top}/${sub}`);
78
76
  if (stat.isFile()) {
79
77
  if (valid || STD_TOP_FILES.has(sub)) {
@@ -87,11 +85,7 @@ export class ManifestModuleUtil {
87
85
  }
88
86
  }
89
87
 
90
- if (!mainLike) {
91
- this.#scanCache[folder] = out;
92
- }
93
-
94
- return out;
88
+ return this.#scanCache[key] = out;
95
89
  }
96
90
 
97
91
  /**
@@ -177,12 +171,13 @@ export class ManifestModuleUtil {
177
171
  /**
178
172
  * Visit a module and describe files, and metadata
179
173
  */
180
- static async describeModule(ctx: ManifestContext, dep: ModuleDep): Promise<ManifestModule> {
181
- const { main, mainLike, local, name, version, sourcePath, roleSet, prod, parentSet, internal } = dep;
174
+ static async describeModule(ctx: ManifestContext, mod: PackageModule): Promise<ManifestModule> {
175
+ const { state, ...rest } = mod;
176
+ const sourcePath = path.resolve(ctx.workspace.path, rest.sourceFolder);
182
177
 
183
178
  const files: ManifestModule['files'] = {};
184
179
 
185
- for (const file of await this.scanFolder(sourcePath, mainLike)) {
180
+ for (const file of await this.scanFolder(sourcePath, rest.main)) {
186
181
  // Group by top folder
187
182
  const moduleFile = file.replace(`${sourcePath}/`, '');
188
183
  const entry = await this.transformFile(moduleFile, file);
@@ -190,30 +185,20 @@ export class ManifestModuleUtil {
190
185
  (files[key] ??= []).push(entry);
191
186
  }
192
187
 
193
- // Refine non-main source, remove anything in root that is source (doesn't include $index)
194
- if (!mainLike) {
195
- files.$root = files.$root?.filter(([file, type]) => type !== 'ts');
196
- }
197
-
198
- const roles = [...roleSet ?? []].sort();
199
- const parents = [...parentSet].sort();
200
- const outputFolder = `node_modules/${name}`;
201
- const sourceFolder = sourcePath === ctx.workspace.path ? '' : sourcePath.replace(`${ctx.workspace.path}/`, '');
202
-
203
- const res: ManifestModule = {
204
- main, name, version, local, internal, sourceFolder, outputFolder, roles, parents, prod, files
188
+ return {
189
+ ...rest,
190
+ roles: [...state.roleSet].sort(),
191
+ parents: [...state.parentSet].sort(),
192
+ files
205
193
  };
206
- return res;
207
194
  }
208
195
 
209
196
  /**
210
197
  * Produce all modules for a given manifest folder, adding in some given modules when developing framework
211
198
  */
212
199
  static async produceModules(ctx: ManifestContext): Promise<Record<string, ManifestModule>> {
213
- const visitor = new ModuleDependencyVisitor(ctx);
214
- const declared = await PackageUtil.visitPackages(visitor);
215
- const sorted = [...declared].sort((a, b) => a.name.localeCompare(b.name));
216
- const modules = await Promise.all(sorted.map(x => this.describeModule(ctx, x)));
200
+ const pkgs = await new PackageModuleVisitor(ctx).visit();
201
+ const modules = await Promise.all([...pkgs].map(x => this.describeModule(ctx, x)));
217
202
  return Object.fromEntries(modules.map(m => [m.name, m]));
218
203
  }
219
204
 
package/src/package.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  import { createRequire } from 'node:module';
2
2
  import { execSync } from 'node:child_process';
3
3
 
4
- import type { ManifestContext, NodePackageManager, Package, PackageVisitor, PackageVisitReq, PackageWorkspaceEntry } from './types';
5
4
  import { path } from './path';
6
5
  import { ManifestFileUtil } from './file';
7
6
 
7
+ import { PackagePath, type Package, type PackageWorkspaceEntry } from './types/package';
8
+ import type { ManifestContext } from './types/context';
9
+ import type { NodePackageManager } from './types/common';
10
+
8
11
  /**
9
12
  * Utilities for querying, traversing and reading package.json files.
10
13
  */
@@ -31,9 +34,9 @@ export class PackageUtil {
31
34
  /**
32
35
  * Resolve version path, if file: url
33
36
  */
34
- static resolveVersionPath(rootPath: string, ver: string): string | undefined {
37
+ static resolveVersionPath(root: Package, ver: string): string | undefined {
35
38
  if (ver.startsWith('file:')) {
36
- return path.resolve(rootPath, ver.replace('file:', ''));
39
+ return path.resolve(this.getPackagePath(root), ver.replace('file:', ''));
37
40
  } else {
38
41
  return;
39
42
  }
@@ -54,31 +57,6 @@ export class PackageUtil {
54
57
  throw new Error(`Unable to resolve: ${name}`);
55
58
  }
56
59
 
57
- /**
58
- * Build a package visit req
59
- */
60
- static packageReq<T>(sourcePath: string, prod: boolean, topLevel?: boolean): PackageVisitReq<T> {
61
- return { pkg: this.readPackage(sourcePath), sourcePath, prod, topLevel };
62
- }
63
-
64
- /**
65
- * Extract all dependencies from a package
66
- */
67
- static getAllDependencies<T = unknown>(modulePath: string, local: boolean): PackageVisitReq<T>[] {
68
- const pkg = this.readPackage(modulePath);
69
- const children: Record<string, PackageVisitReq<T>> = {};
70
- for (const [deps, prod] of [
71
- [pkg.dependencies, true],
72
- ...(local ? [[pkg.devDependencies, false] as const] : []),
73
- ] as const) {
74
- for (const [name, version] of Object.entries(deps ?? {})) {
75
- const depPath = this.resolveVersionPath(modulePath, version) ?? this.resolvePackagePath(name);
76
- children[`${name}#${version}`] = this.packageReq<T>(depPath, prod, false);
77
- }
78
- }
79
- return Object.values(children).sort((a, b) => a.pkg.name.localeCompare(b.pkg.name));
80
- }
81
-
82
60
  /**
83
61
  * Read a package.json from a given folder
84
62
  */
@@ -92,86 +70,37 @@ export class PackageUtil {
92
70
 
93
71
  res.name ??= 'untitled'; // If a package.json (root-only) is missing a name, allows for npx execution
94
72
 
73
+ res[PackagePath] = modulePath;
95
74
  return res;
96
75
  }
97
76
 
98
77
  /**
99
- * import a package.json from a given module name
100
- */
101
- static importPackage(moduleName: string): Package {
102
- return this.readPackage(this.resolvePackagePath(moduleName));
103
- }
104
-
105
- /**
106
- * Visit packages with ability to track duplicates
78
+ * Get the package path
107
79
  */
108
- static async visitPackages<T>(visitor: PackageVisitor<T>): Promise<Set<T>> {
109
-
110
- const root = this.packageReq<T>(visitor.rootPath, false, true);
111
-
112
- const seen = new Map<string, T>();
113
- const queue: PackageVisitReq<T>[] = [...await visitor.init?.(root) ?? [], root];
114
- const out = new Set<T>();
115
-
116
- while (queue.length) {
117
- const req = queue.pop();
118
-
119
- if (!req || (visitor.valid && !visitor.valid(req))) {
120
- continue;
121
- }
122
-
123
- const key = req.sourcePath;
124
- if (seen.has(key)) {
125
- await visitor.visit?.(req, seen.get(key)!);
126
- } else {
127
- const dep = await visitor.create(req);
128
- out.add(dep);
129
- await visitor.visit?.(req, dep);
130
- seen.set(key, dep);
131
- const children = this.getAllDependencies<T>(
132
- req.sourcePath,
133
- // We consider a module local if its not in the node_modules
134
- !req.sourcePath.includes('node_modules') && (
135
- // And its the root or we are in a monorepo
136
- root.sourcePath === req.sourcePath ||
137
- !!root.pkg.workspaces
138
- )
139
- );
140
- queue.push(...children.map(x => ({ ...x, parent: dep })));
141
- }
142
- }
143
- return (await visitor.complete?.(out)) ?? out;
80
+ static getPackagePath(pkg: Package): string {
81
+ return pkg[PackagePath];
144
82
  }
145
83
 
146
84
  /**
147
85
  * Find workspace values from rootPath
148
86
  */
149
- static async resolveWorkspaces(ctx: ManifestContext, rootPath: string): Promise<PackageWorkspaceEntry[]> {
150
- if (!this.#workspaces[rootPath]) {
151
- const cache = path.resolve(ctx.workspace.path, ctx.build.outputFolder, 'workspaces.json');
152
- try {
153
- return await ManifestFileUtil.readAsJson(cache);
154
- } catch (err) {
87
+ static async resolveWorkspaces(ctx: ManifestContext): Promise<PackageWorkspaceEntry[]> {
88
+ const rootPath = ctx.workspace.path;
89
+ const cache = path.resolve(rootPath, ctx.build.outputFolder, 'workspaces.json');
90
+ return this.#workspaces[rootPath] ??= await ManifestFileUtil.readAsJson<PackageWorkspaceEntry[]>(cache)
91
+ .catch(async () => {
155
92
  let out: PackageWorkspaceEntry[];
156
93
  switch (ctx.workspace.manager) {
94
+ case 'yarn':
157
95
  case 'npm': {
158
96
  const res = await this.#exec<{ location: string, name: string }[]>(rootPath, 'npm query .workspace');
159
- out = res.map(d => ({ sourcePath: d.location, name: d.name }));
160
- break;
161
- }
162
- case 'yarn': {
163
- const res = await this.#exec<Record<string, { location: string }>>(rootPath, 'npm query .workspace');
164
- out = Object.entries(res).map(([name, { location }]) => ({ sourcePath: location, name }));
97
+ out = res.map(d => ({ path: path.resolve(ctx.workspace.path, d.location), name: d.name }));
165
98
  break;
166
99
  }
167
100
  }
168
-
169
- this.#workspaces[rootPath] = out;
170
-
171
101
  await ManifestFileUtil.bufferedFileWrite(cache, out);
172
- }
173
- }
174
- return this.#workspaces[rootPath];
102
+ return out;
103
+ });
175
104
  }
176
105
 
177
106
  /**
package/src/runtime.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import { path } from './path';
2
- import { IndexedModule, ManifestIndex } from './manifest-index';
3
- import { FunctionMetadata, ManifestContext, ManifestModule } from './types';
2
+ import { ManifestIndex } from './manifest-index';
3
+
4
+ import type { FunctionMetadata } from './types/common';
5
+ import type { IndexedModule, ManifestModule } from './types/manifest';
6
+ import type { ManifestContext } from './types/context';
4
7
 
5
8
  const METADATA = Symbol.for('@travetto/manifest:metadata');
6
9
  type Metadated = { [METADATA]: FunctionMetadata };
@@ -122,5 +125,19 @@ export const RuntimeContext = build({
122
125
  */
123
126
  workspaceRelative(...rel: string[]): string {
124
127
  return path.resolve(RuntimeIndex.manifest.workspace.path, ...rel);
128
+ },
129
+ /**
130
+ * Produce a workspace path for tooling, with '@' being replaced by node_module/name folder
131
+ * @param rel The relative path
132
+ */
133
+ toolPath(...rel: string[]): string {
134
+ rel = rel.flatMap(x => x === '@' ? ['node_modules', RuntimeIndex.manifest.main.name] : [x]);
135
+ return path.resolve(RuntimeIndex.manifest.workspace.path, RuntimeIndex.manifest.build.toolFolder, ...rel);
136
+ },
137
+ /**
138
+ * Are we running from a mono-root?
139
+ */
140
+ get monoRoot(): boolean {
141
+ return !!RuntimeIndex.manifest.workspace.mono && !RuntimeIndex.manifest.main.folder;
125
142
  }
126
143
  }, ['main', 'workspace']);
@@ -0,0 +1,20 @@
1
+ export type NodeModuleType = 'module' | 'commonjs';
2
+ export type NodePackageManager = 'yarn' | 'npm';
3
+
4
+ export type ManifestModuleFileType = 'typings' | 'ts' | 'js' | 'json' | 'package-json' | 'unknown' | 'fixture' | 'md';
5
+ export type ManifestModuleFolderType =
6
+ '$root' | '$index' | '$package' |
7
+ 'src' | 'bin' | 'support' | 'resources' | 'test' | 'doc' |
8
+ 'test/fixtures' | 'support/fixtures' | 'support/resources' |
9
+ '$other' | '$transformer';
10
+
11
+ export type ManifestModuleRole = 'std' | 'test' | 'doc' | 'compile' | 'build';
12
+
13
+ export type FunctionMetadata = {
14
+ id: string;
15
+ source: string;
16
+ hash?: number;
17
+ methods?: Record<string, { hash: number }>;
18
+ synthetic?: boolean;
19
+ abstract?: boolean;
20
+ };
@@ -0,0 +1,40 @@
1
+ import type { NodeModuleType, NodePackageManager } from './common';
2
+
3
+ export type ManifestContext = {
4
+ workspace: {
5
+ /** Workspace path for module */
6
+ path: string;
7
+ /** The module name for the workspace root */
8
+ name: string;
9
+ /** Is the workspace a monorepo? */
10
+ mono?: boolean;
11
+ /** The module type of the workspace */
12
+ type: NodeModuleType;
13
+ /** The package manager of the workspace */
14
+ manager: NodePackageManager;
15
+ /** The default env name */
16
+ defaultEnv: string;
17
+ };
18
+ build: {
19
+ /** Compiler folder, relative to workspace */
20
+ compilerFolder: string;
21
+ /** Compiler module folder */
22
+ compilerModuleFolder: string;
23
+ /** URL for the compiler server */
24
+ compilerUrl: string;
25
+ /** Code output folder, relative to workspace */
26
+ outputFolder: string;
27
+ /** Location of development-time tool output */
28
+ toolFolder: string;
29
+ };
30
+ main: {
31
+ /** Main module for manifest */
32
+ name: string;
33
+ /** Folder, relative to workspace for main module */
34
+ folder: string;
35
+ /** Description of the main module */
36
+ description?: string;
37
+ /** Version of the main module */
38
+ version: string;
39
+ };
40
+ };
@@ -0,0 +1,79 @@
1
+ import type { ManifestModuleFileType, ManifestModuleFolderType, ManifestModuleRole } from './common';
2
+ import type { ManifestContext } from './context';
3
+ import { Package } from './package';
4
+
5
+ export type ManifestModuleFile = [string, ManifestModuleFileType, number] | [string, ManifestModuleFileType, number, ManifestModuleRole];
6
+
7
+ export type ManifestDepCore = {
8
+ /** Package name */
9
+ name: string;
10
+ /** Package version */
11
+ version: string;
12
+ /** Is this the main module */
13
+ main?: boolean;
14
+ /** Is this a module that is part of the workspace */
15
+ workspace?: boolean;
16
+ /** Should this module be deployed to prod? */
17
+ prod: boolean;
18
+ /** Is the module intended to be published? */
19
+ internal?: boolean;
20
+ };
21
+
22
+ export type ManifestModuleCore = ManifestDepCore & {
23
+ sourceFolder: string;
24
+ outputFolder: string;
25
+ roles: ManifestModuleRole[];
26
+ parents: string[];
27
+ };
28
+
29
+ export type ManifestModule = ManifestModuleCore & {
30
+ files: Partial<Record<ManifestModuleFolderType, ManifestModuleFile[]>>;
31
+ };
32
+
33
+ export type ManifestRoot = ManifestContext & {
34
+ generated: number;
35
+ modules: Record<string, ManifestModule>;
36
+ };
37
+
38
+ export type FindConfig = {
39
+ folder?: (folder: ManifestModuleFolderType) => boolean;
40
+ module?: (module: IndexedModule) => boolean;
41
+ file?: (file: IndexedFile) => boolean;
42
+ sourceOnly?: boolean;
43
+ };
44
+
45
+ export type IndexedFile = {
46
+ id: string;
47
+ import: string;
48
+ module: string;
49
+ sourceFile: string;
50
+ outputFile: string;
51
+ relativeFile: string;
52
+ role: ManifestModuleRole;
53
+ type: ManifestModuleFileType;
54
+ };
55
+
56
+ export type IndexedModule = ManifestModuleCore & {
57
+ sourcePath: string;
58
+ outputPath: string;
59
+ files: Record<ManifestModuleFolderType, IndexedFile[]>;
60
+ children: Set<string>;
61
+ };
62
+
63
+ /** Module dependency, used in dependency visiting */
64
+ export type PackageModule = Omit<ManifestModule, 'files' | 'parents' | 'roles'> & {
65
+ state: {
66
+ /** Role root? */
67
+ roleRoot?: boolean;
68
+ /** Travetto package info */
69
+ travetto?: Package['travetto'];
70
+ /** Prod dependencies */
71
+ prodDeps: Set<string>;
72
+ /** Set of parent package names */
73
+ parentSet: Set<string>;
74
+ /** Set of child package names */
75
+ childSet: Set<string>;
76
+ /** Defined roles for a given module */
77
+ roleSet: Set<ManifestModuleRole>;
78
+ };
79
+ };
@@ -0,0 +1,56 @@
1
+ import type { ManifestModuleRole, NodeModuleType } from './common';
2
+ import type { ManifestContext } from './context';
3
+
4
+ export const PackagePath = Symbol.for('@travetto/manifest:package-path');
5
+
6
+ export type Package = {
7
+ [PackagePath]: string;
8
+ name: string;
9
+ type?: NodeModuleType;
10
+ version: string;
11
+ description?: string;
12
+ license?: string;
13
+ repository?: {
14
+ url: string;
15
+ directory?: string;
16
+ };
17
+ author?: {
18
+ email?: string;
19
+ name?: string;
20
+ };
21
+ main: string;
22
+ homepage?: string;
23
+ files?: string[];
24
+ bin?: Record<string, string>;
25
+ scripts?: Record<string, string>;
26
+ engines?: Record<string, string>;
27
+ keywords?: string[];
28
+
29
+ dependencies?: Record<string, string>;
30
+ devDependencies?: Record<string, string>;
31
+ peerDependencies?: Record<string, string>;
32
+ peerDependenciesMeta?: Record<string, { optional?: boolean }>;
33
+ optionalDependencies?: Record<string, string>;
34
+ travetto?: {
35
+ displayName?: string;
36
+ roles?: ManifestModuleRole[];
37
+ doc?: {
38
+ output?: string[];
39
+ root?: string;
40
+ baseUrl?: string;
41
+ outputs?: string[];
42
+ };
43
+ defaultEnv?: string;
44
+ build?: Partial<ManifestContext['build']> & {
45
+ isolated?: boolean;
46
+ withModules?: Record<string, 'main' | true>;
47
+ };
48
+ };
49
+ workspaces?: string[];
50
+ private?: boolean;
51
+ publishConfig?: { access?: 'restricted' | 'public' };
52
+ };
53
+
54
+ export type PackageDepType = 'dependencies' | 'devDependencies' | 'optionalDependencies' | 'peerDependencies';
55
+
56
+ export type PackageWorkspaceEntry = { name: string, path: string };