@travetto/manifest 3.4.0 → 4.0.0-rc.1

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/src/util.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  import { path } from './path';
2
- import { ManifestContext, ManifestRoot } from './types';
3
2
  import { ManifestModuleUtil } from './module';
4
3
  import { ManifestFileUtil } from './file';
4
+ import { PackageUtil } from './package';
5
+
6
+ import type { ManifestContext } from './types/context';
7
+ import type { ManifestRoot } from './types/manifest';
5
8
 
6
9
  const MANIFEST_FILE = 'manifest.json';
7
10
 
@@ -9,41 +12,46 @@ const MANIFEST_FILE = 'manifest.json';
9
12
  * Manifest utils
10
13
  */
11
14
  export class ManifestUtil {
12
- /**
13
- * Build a manifest context
14
- * @param folder
15
- */
16
- static async buildContext(folder?: string): Promise<ManifestContext> {
17
- const { getManifestContext } = await import('../bin/context.js');
18
- return getManifestContext(folder);
19
- }
20
-
21
15
  /**
22
16
  * Produce manifest in memory
23
17
  */
24
18
  static async buildManifest(ctx: ManifestContext): Promise<ManifestRoot> {
25
19
  return {
26
- modules: await ManifestModuleUtil.produceModules(ctx),
27
20
  generated: Date.now(),
28
- ...ctx
21
+ workspace: ctx.workspace,
22
+ build: ctx.build,
23
+ main: ctx.main,
24
+ modules: await ManifestModuleUtil.produceModules(ctx),
29
25
  };
30
26
  }
31
27
 
28
+ /**
29
+ * Produce a manifest location given a current context and a module name
30
+ */
31
+ static getManifestLocation(ctx: ManifestContext, module?: string): string {
32
+ return path.resolve(ctx.workspace.path, ctx.build.outputFolder, 'node_modules', module ?? ctx.workspace.name);
33
+ }
34
+
32
35
  /**
33
36
  * Produce a production manifest from a given manifest
34
37
  */
35
38
  static createProductionManifest(manifest: ManifestRoot): ManifestRoot {
39
+ const prodModules = Object.values(manifest.modules).filter(x => x.prod);
40
+ const prodModNames = new Set([...prodModules.map(x => x.name)]);
36
41
  return {
37
- ...manifest,
38
- // If in prod mode, only include std modules
42
+ generated: manifest.generated,
43
+ workspace: manifest.workspace,
44
+ build: {
45
+ ...manifest.build,
46
+ // Mark output folder/workspace path as portable
47
+ outputFolder: '$$PRODUCTION$$',
48
+ },
49
+ main: manifest.main,
39
50
  modules: Object.fromEntries(
40
- Object.values(manifest.modules)
41
- .filter(x => x.prod)
42
- .map(m => [m.name, m])
51
+ prodModules.map(m => [m.name, Object.assign(m, {
52
+ parents: m.parents.filter(x => prodModNames.has(x))
53
+ })])
43
54
  ),
44
- // Mark output folder/workspace path as portable
45
- outputFolder: '',
46
- workspacePath: '',
47
55
  };
48
56
  }
49
57
 
@@ -53,27 +61,27 @@ export class ManifestUtil {
53
61
  * @param file
54
62
  * @returns
55
63
  */
56
- static readManifestSync(file: string): { manifest: ManifestRoot, file: string } {
64
+ static readManifestSync(file: string): ManifestRoot {
57
65
  file = path.resolve(file);
58
66
  if (!file.endsWith('.json')) {
59
67
  file = path.resolve(file, MANIFEST_FILE);
60
68
  }
61
69
  const manifest: ManifestRoot = ManifestFileUtil.readAsJsonSync(file);
62
- // Support packaged environments, by allowing empty outputFolder
63
- if (!manifest.outputFolder) {
64
- manifest.outputFolder = path.cwd();
65
- manifest.workspacePath = path.cwd();
70
+ // Support packaged environments, by allowing empty manifest.build.outputFolder
71
+ if (manifest.build.outputFolder === '$$PRODUCTION$$') {
72
+ manifest.build.outputFolder = path.cwd();
73
+ manifest.workspace.path = path.cwd();
66
74
  }
67
- return { manifest, file };
75
+ return manifest;
68
76
  }
69
77
 
70
78
  /**
71
79
  * Write manifest for a given context, return location
72
80
  */
73
- static writeManifest(ctx: ManifestContext, manifest: ManifestRoot): Promise<string> {
74
- return ManifestFileUtil.bufferedFileWrite(
75
- path.resolve(ctx.workspacePath, ctx.outputFolder, 'node_modules', ctx.mainModule, MANIFEST_FILE),
76
- JSON.stringify(manifest)
81
+ static writeManifest(manifest: ManifestRoot): Promise<string> {
82
+ return this.writeManifestToFile(
83
+ path.resolve(manifest.workspace.path, manifest.build.outputFolder, 'node_modules', manifest.main.name),
84
+ manifest
77
85
  );
78
86
  }
79
87
 
@@ -91,11 +99,75 @@ export class ManifestUtil {
91
99
  }
92
100
 
93
101
  /**
94
- * Rewrite manifest for a given folder
102
+ * Produce the manifest context for the workspace module
95
103
  */
96
- static async rewriteManifest(source: string): Promise<void> {
97
- const subCtx = await this.buildContext(source);
98
- const subManifest = await this.buildManifest(subCtx);
99
- await this.writeManifest(subCtx, subManifest);
104
+ static getWorkspaceContext(ctx: ManifestContext): ManifestContext {
105
+ return ctx.workspace.mono ? {
106
+ workspace: ctx.workspace,
107
+ build: ctx.build,
108
+ main: {
109
+ name: ctx.workspace.name,
110
+ folder: '',
111
+ version: '0.0.0',
112
+ }
113
+ } : ctx;
114
+ }
115
+
116
+ /**
117
+ * Produce the manifest context for a given module module
118
+ */
119
+ static getModuleContext(ctx: ManifestContext, folder: string): ManifestContext {
120
+ const modPath = path.resolve(ctx.workspace.path, folder);
121
+ const pkg = PackageUtil.readPackage(modPath);
122
+
123
+ return {
124
+ workspace: ctx.workspace,
125
+ build: ctx.build,
126
+ main: {
127
+ name: pkg.name,
128
+ folder,
129
+ version: pkg.version,
130
+ description: pkg.description
131
+ }
132
+ };
133
+ }
134
+
135
+ /**
136
+ * Efficient lookup for path-based graphs
137
+ */
138
+ static lookupTrie<T>(
139
+ inputs: T[], getPath: (v: T) => string[], validateUnknown?: (pth: string[]) => boolean
140
+ ): (pth: string[]) => T | undefined {
141
+ type TrieNode = { value?: T, subs: Record<string, TrieNode> };
142
+ const root: TrieNode = { subs: {} };
143
+ for (const item of inputs) {
144
+ const pth = getPath(item);
145
+ let node = root;
146
+ for (const sub of pth) {
147
+ if (sub) {
148
+ node = node.subs[sub] ??= { subs: {} };
149
+ }
150
+ }
151
+ node.value = item;
152
+ }
153
+
154
+ return pth => {
155
+ let node = root;
156
+ let value = node.value;
157
+ let i = 0;
158
+
159
+ for (const sub of pth) {
160
+ i += 1;
161
+ if (node) {
162
+ node = node.subs[sub];
163
+ value = node?.value ?? value;
164
+ } else if (validateUnknown && !node && !validateUnknown(pth.slice(0, i))) {
165
+ value = undefined;
166
+ break;
167
+ }
168
+ }
169
+
170
+ return value;
171
+ };
100
172
  }
101
173
  }
@@ -9,16 +9,16 @@ const MANIFEST_MOD = '@travetto/manifest';
9
9
  const MANIFEST_IDX = `${MANIFEST_MOD}/__index__`;
10
10
  const ENTRY_POINT = 'support/entry';
11
11
 
12
- const ROOT_IDX_IMPORT = `${MANIFEST_MOD}/src/root-index`;
13
- const ROOT_IDX_CLS = 'RootIndex';
12
+ const RUNTIME_IDX_IMPORT = `${MANIFEST_MOD}/src/runtime`;
13
+ const RUNTIME_IDX_CLS = 'RuntimeIndex';
14
14
 
15
15
  const methods = Symbol.for(`${MANIFEST_MOD}:methods`);
16
16
  const cls = Symbol.for(`${MANIFEST_MOD}:class`);
17
17
  const fn = Symbol.for(`${MANIFEST_MOD}:function`);
18
- const rootIdx = Symbol.for(`${MANIFEST_MOD}:rootIndex`);
18
+ const runtimeIdx = Symbol.for(`${MANIFEST_MOD}:runtimeIndex`);
19
19
 
20
20
  interface MetadataInfo {
21
- [rootIdx]?: Import;
21
+ [runtimeIdx]?: Import;
22
22
  [methods]?: {
23
23
  [key: string]: { hash: number };
24
24
  };
@@ -72,8 +72,8 @@ export class RegisterTransformer {
72
72
  return node;
73
73
  }
74
74
 
75
- state[rootIdx] ??= state.importFile(ROOT_IDX_IMPORT);
76
- const ident = state.createAccess(state[rootIdx].ident, ROOT_IDX_CLS);
75
+ state[runtimeIdx] ??= state.importFile(RUNTIME_IDX_IMPORT);
76
+ const ident = state.createAccess(state[runtimeIdx].ident, RUNTIME_IDX_CLS);
77
77
 
78
78
  const name = node.name?.escapedText.toString() ?? '';
79
79
 
@@ -117,8 +117,8 @@ export class RegisterTransformer {
117
117
 
118
118
  if (ts.isFunctionDeclaration(node) && node.name && node.parent && ts.isSourceFile(node.parent)) {
119
119
  // If we have a class like function
120
- state[rootIdx] ??= state.importFile(ROOT_IDX_IMPORT);
121
- const ident = state.createAccess(state[rootIdx].ident, ROOT_IDX_CLS);
120
+ state[runtimeIdx] ??= state.importFile(RUNTIME_IDX_IMPORT);
121
+ const ident = state.createAccess(state[runtimeIdx].ident, RUNTIME_IDX_CLS);
122
122
  const meta = state.factory.createCallExpression(
123
123
  state.createAccess(ident, 'registerFunction'),
124
124
  [],
package/src/types.ts DELETED
@@ -1,118 +0,0 @@
1
- export type NodeModuleType = 'module' | 'commonjs';
2
-
3
- export type ManifestModuleFileType = 'typings' | 'ts' | 'js' | 'json' | 'package-json' | 'unknown' | 'fixture' | 'md';
4
- export type ManifestModuleFolderType =
5
- '$root' | '$index' | '$package' |
6
- 'src' | 'bin' | 'support' | 'resources' | 'test' | 'doc' |
7
- 'test/fixtures' | 'support/fixtures' | 'support/resources' |
8
- '$other' | '$transformer';
9
-
10
- export type ManifestModuleRole = 'std' | 'test' | 'doc' | 'compile' | 'build';
11
-
12
- export type ManifestModuleFile = [string, ManifestModuleFileType, number] | [string, ManifestModuleFileType, number, ManifestModuleRole];
13
- export type ManifestModuleCore = {
14
- name: string;
15
- main?: boolean;
16
- local?: boolean;
17
- version: string;
18
- sourceFolder: string;
19
- outputFolder: string;
20
- prod: boolean;
21
- roles: ManifestModuleRole[];
22
- parents: string[];
23
- internal?: boolean;
24
- };
25
-
26
- export type ManifestModule = ManifestModuleCore & {
27
- files: Partial<Record<ManifestModuleFolderType, ManifestModuleFile[]>>;
28
- };
29
-
30
- export type ManifestContext = {
31
- mainModule: string;
32
- mainFolder: string;
33
- workspacePath: string;
34
- outputFolder: string;
35
- toolFolder: string;
36
- compilerFolder: string;
37
- monoRepo?: boolean;
38
- moduleType: NodeModuleType;
39
- packageManager: 'yarn' | 'npm';
40
- frameworkVersion: string;
41
- description?: string;
42
- version: string;
43
- compilerUrl: string;
44
- };
45
-
46
- export type ManifestRoot = ManifestContext & {
47
- generated: number;
48
- modules: Record<string, ManifestModule>;
49
- };
50
-
51
- export type Package = {
52
- name: string;
53
- type?: NodeModuleType;
54
- version: string;
55
- description?: string;
56
- license?: string;
57
- repository?: {
58
- url: string;
59
- directory?: string;
60
- };
61
- author?: {
62
- email?: string;
63
- name?: string;
64
- };
65
- main: string;
66
- homepage?: string;
67
- files?: string[];
68
- bin?: Record<string, string>;
69
- scripts?: Record<string, string>;
70
- engines?: Record<string, string>;
71
- keywords?: string[];
72
-
73
- dependencies?: Record<string, string>;
74
- devDependencies?: Record<string, string>;
75
- peerDependencies?: Record<string, string>;
76
- peerDependenciesMeta?: Record<string, { optional?: boolean }>;
77
- optionalDependencies?: Record<string, string>;
78
- travetto?: {
79
- isolated?: boolean;
80
- displayName?: string;
81
- roles?: ManifestModuleRole[];
82
- globalModules?: string[];
83
- mainSource?: string[];
84
- docOutput?: string[];
85
- docRoot?: string;
86
- docBaseUrl?: string;
87
- docOutputs?: string[];
88
- outputFolder?: string;
89
- toolFolder?: string;
90
- compilerFolder?: string;
91
- compilerUrl?: string;
92
- };
93
- workspaces?: string[];
94
- private?: boolean;
95
- publishConfig?: { access?: 'restricted' | 'public' };
96
- };
97
-
98
- type OrProm<T> = T | Promise<T>;
99
-
100
- export type PackageVisitReq<T> = { pkg: Package, prod: boolean, sourcePath: string, parent?: T, topLevel?: boolean };
101
- export type PackageVisitor<T> = {
102
- init?(req: PackageVisitReq<T>): OrProm<undefined | void | PackageVisitReq<T>[]>;
103
- valid?(req: PackageVisitReq<T>): boolean;
104
- create(req: PackageVisitReq<T>): OrProm<T>;
105
- visit?(req: PackageVisitReq<T>, item: T): OrProm<void>;
106
- complete?(values: Set<T>): OrProm<Set<T> | undefined>;
107
- };
108
-
109
- export type PackageWorkspaceEntry = { name: string, sourcePath: string };
110
-
111
- export type FunctionMetadata = {
112
- id: string;
113
- source: string;
114
- hash?: number;
115
- methods?: Record<string, { hash: number }>;
116
- synthetic?: boolean;
117
- abstract?: boolean;
118
- };
File without changes