@happyvertical/smrt-core 0.57.46 → 0.57.48
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/AGENTS.md +11 -3
- package/agents/browser-entry.md +16 -0
- package/agents/build-knowledge.md +58 -14
- package/agents/change-feed.md +20 -0
- package/agents/generators.md +69 -3
- package/agents/schema-paths.md +82 -0
- package/dist/_virtual/_rolldown/runtime.js +22 -1
- package/dist/browser.d.ts +2 -2
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +2 -2
- package/dist/cascade.d.ts +46 -0
- package/dist/cascade.d.ts.map +1 -1
- package/dist/cascade.js +96 -7
- package/dist/cascade.js.map +1 -1
- package/dist/change-feed.d.ts.map +1 -1
- package/dist/change-feed.js +7 -4
- package/dist/change-feed.js.map +1 -1
- package/dist/class.d.ts.map +1 -1
- package/dist/class.js +3 -3
- package/dist/class.js.map +1 -1
- package/dist/consumer-plugin/index.d.ts +13 -0
- package/dist/consumer-plugin/index.d.ts.map +1 -1
- package/dist/consumer-plugin/index.js +69 -13
- package/dist/consumer-plugin/index.js.map +1 -1
- package/dist/consumer-plugin.js +2 -2
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +3 -3
- package/dist/database.js.map +1 -1
- package/dist/dispatch/bus.d.ts.map +1 -1
- package/dist/dispatch/bus.js +1 -4
- package/dist/dispatch/bus.js.map +1 -1
- package/dist/dispatch/index.d.ts +1 -1
- package/dist/dispatch/index.d.ts.map +1 -1
- package/dist/dispatch/types.d.ts +22 -3
- package/dist/dispatch/types.d.ts.map +1 -1
- package/dist/generators/changes-route.d.ts.map +1 -1
- package/dist/generators/changes-route.js +2 -2
- package/dist/generators/changes-route.js.map +1 -1
- package/dist/generators/custom-action.d.ts +11 -0
- package/dist/generators/custom-action.d.ts.map +1 -1
- package/dist/generators/custom-action.js +23 -4
- package/dist/generators/custom-action.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/lazy-config.d.ts +120 -3
- package/dist/lazy-config.d.ts.map +1 -1
- package/dist/lazy-config.js +81 -10
- package/dist/lazy-config.js.map +1 -1
- package/dist/manifest/generator.d.ts +8 -2
- package/dist/manifest/generator.d.ts.map +1 -1
- package/dist/manifest/generator.js +6 -5
- package/dist/manifest/generator.js.map +1 -1
- package/dist/manifest/index.d.ts +1 -0
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +2 -1
- package/dist/manifest/index.js.map +1 -1
- package/dist/manifest/local-manifest-reader.d.ts +13 -2
- package/dist/manifest/local-manifest-reader.d.ts.map +1 -1
- package/dist/manifest/local-manifest-reader.js +38 -6
- package/dist/manifest/local-manifest-reader.js.map +1 -1
- package/dist/manifest/manifest-loader.d.ts +9 -8
- package/dist/manifest/manifest-loader.d.ts.map +1 -1
- package/dist/manifest/manifest-loader.js +67 -27
- package/dist/manifest/manifest-loader.js.map +1 -1
- package/dist/manifest/object-declarations.d.ts +116 -0
- package/dist/manifest/object-declarations.d.ts.map +1 -0
- package/dist/manifest/object-declarations.js +161 -0
- package/dist/manifest/object-declarations.js.map +1 -0
- package/dist/manifest/static-manifest.d.ts.map +1 -1
- package/dist/manifest/static-manifest.js +5 -3
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.d.ts.map +1 -1
- package/dist/manifest/store.js +18 -2
- package/dist/manifest/store.js.map +1 -1
- package/dist/manifest/test-artifacts.d.ts +57 -0
- package/dist/manifest/test-artifacts.d.ts.map +1 -0
- package/dist/manifest/test-artifacts.js +111 -0
- package/dist/manifest/test-artifacts.js.map +1 -0
- package/dist/manifest.js +2 -1
- package/dist/manifest.json +5 -3
- package/dist/migrations/differ.d.ts.map +1 -1
- package/dist/migrations/differ.js +11 -3
- package/dist/migrations/differ.js.map +1 -1
- package/dist/migrations/index.d.ts +2 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +3 -1
- package/dist/migrations/qualified-name-aliases.d.ts.map +1 -1
- package/dist/migrations/qualified-name-aliases.js +1 -1
- package/dist/migrations/qualified-name-aliases.js.map +1 -1
- package/dist/migrations.js +3 -1
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +2 -2
- package/dist/object.js.map +1 -1
- package/dist/postgres-permissions.d.ts.map +1 -1
- package/dist/postgres-permissions.js +4 -3
- package/dist/postgres-permissions.js.map +1 -1
- package/dist/postgres-timeouts.d.ts +30 -3
- package/dist/postgres-timeouts.d.ts.map +1 -1
- package/dist/postgres-timeouts.js +39 -2
- package/dist/postgres-timeouts.js.map +1 -1
- package/dist/prebuild/index.d.ts.map +1 -1
- package/dist/prebuild/index.js +14 -11
- package/dist/prebuild/index.js.map +1 -1
- package/dist/registry/class-registration.d.ts.map +1 -1
- package/dist/registry/class-registration.js +24 -2
- package/dist/registry/class-registration.js.map +1 -1
- package/dist/registry/collection-exposure.d.ts +27 -0
- package/dist/registry/collection-exposure.d.ts.map +1 -1
- package/dist/registry/collection-exposure.js +74 -1
- package/dist/registry/collection-exposure.js.map +1 -1
- package/dist/registry/collection-resolution.d.ts.map +1 -1
- package/dist/registry/collection-resolution.js +1 -0
- package/dist/registry/collection-resolution.js.map +1 -1
- package/dist/registry/framework-base-classes.d.ts.map +1 -1
- package/dist/registry/framework-base-classes.js +5 -0
- package/dist/registry/framework-base-classes.js.map +1 -1
- package/dist/registry/schema-builder.d.ts +8 -1
- package/dist/registry/schema-builder.d.ts.map +1 -1
- package/dist/registry/schema-builder.js +17 -4
- package/dist/registry/schema-builder.js.map +1 -1
- package/dist/registry/types.d.ts +12 -0
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry.d.ts +2 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +30 -10
- package/dist/registry.js.map +1 -1
- package/dist/scanner/manifest-generator.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.js +10 -8
- package/dist/scanner/manifest-generator.js.map +1 -1
- package/dist/scanner/types.d.ts +29 -0
- package/dist/scanner/types.d.ts.map +1 -1
- package/dist/scanner/types.js.map +1 -1
- package/dist/schema/generator.d.ts +32 -0
- package/dist/schema/generator.d.ts.map +1 -1
- package/dist/schema/generator.js +59 -0
- package/dist/schema/generator.js.map +1 -1
- package/dist/schema/live-parity.d.ts.map +1 -1
- package/dist/schema/live-parity.js +4 -2
- package/dist/schema/live-parity.js.map +1 -1
- package/dist/scripts/browser-unbundled-dev.mjs +90 -0
- package/dist/scripts/generate-test-manifest.js +9 -49
- package/dist/smrt-knowledge.json +16 -16
- package/dist/system/compatibility.d.ts.map +1 -1
- package/dist/system/compatibility.js +12 -4
- package/dist/system/compatibility.js.map +1 -1
- package/dist/system/schema.d.ts +70 -8
- package/dist/system/schema.d.ts.map +1 -1
- package/dist/system/schema.js +231 -24
- package/dist/system/schema.js.map +1 -1
- package/dist/testing/database.d.ts.map +1 -1
- package/dist/testing/database.js +14 -2
- package/dist/testing/database.js.map +1 -1
- package/dist/tools/tool-generator.d.ts.map +1 -1
- package/dist/tools/tool-generator.js +2 -2
- package/dist/tools/tool-generator.js.map +1 -1
- package/dist/utils/import-workspace-module.d.ts.map +1 -1
- package/dist/utils/import-workspace-module.js +23 -0
- package/dist/utils/import-workspace-module.js.map +1 -1
- package/dist/utils/naming.js +5 -3
- package/dist/utils/naming.js.map +1 -1
- package/dist/vendor/pluralize/pluralize.js +421 -0
- package/dist/vendor/pluralize/pluralize.js.map +1 -0
- package/dist/vite-plugin/api-client-entries.d.ts +5 -1
- package/dist/vite-plugin/api-client-entries.d.ts.map +1 -1
- package/dist/vite-plugin/api-client-entries.js +11 -6
- package/dist/vite-plugin/api-client-entries.js.map +1 -1
- package/dist/vite-plugin/consumer-import.d.ts +28 -0
- package/dist/vite-plugin/consumer-import.d.ts.map +1 -0
- package/dist/vite-plugin/consumer-import.js +42 -0
- package/dist/vite-plugin/consumer-import.js.map +1 -0
- package/dist/vite-plugin/dev-plane-route.d.ts +6 -1
- package/dist/vite-plugin/dev-plane-route.d.ts.map +1 -1
- package/dist/vite-plugin/dev-plane-route.js +8 -9
- package/dist/vite-plugin/dev-plane-route.js.map +1 -1
- package/dist/vite-plugin/index.d.ts.map +1 -1
- package/dist/vite-plugin/index.js +12 -9
- package/dist/vite-plugin/index.js.map +1 -1
- package/dist/vite-plugin/resources-route.d.ts.map +1 -1
- package/dist/vite-plugin/resources-route.js +3 -8
- package/dist/vite-plugin/resources-route.js.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.js +7 -11
- package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
- package/dist/vite-plugin/sync-apply-route.d.ts +16 -0
- package/dist/vite-plugin/sync-apply-route.d.ts.map +1 -1
- package/dist/vite-plugin/sync-apply-route.js +48 -6
- package/dist/vite-plugin/sync-apply-route.js.map +1 -1
- package/package.json +12 -12
package/dist/manifest/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SMRT_TEST_MANIFEST_PATHS_ENV_KEY, isActiveTestManifestPath, isRefusedTestArtifact, isTestArtifactManifest, registerActiveTestManifestPath, resolveActiveTestManifestPath } from "./test-artifacts.js";
|
|
1
2
|
import { discoverManifestEntry, findManifestEntryByQualifiedName, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync } from "./manifest-loader.js";
|
|
2
3
|
import { ManifestGenerator } from "../scanner/manifest-generator.js";
|
|
3
4
|
import { ManifestManager } from "./manager.js";
|
|
@@ -41,6 +42,6 @@ function getManifest() {
|
|
|
41
42
|
return Promise.resolve(manifest);
|
|
42
43
|
}
|
|
43
44
|
//#endregion
|
|
44
|
-
export { ManifestBuilder, ManifestGenerator, ManifestManager, manifest as default, manifest, discoverManifestEntry, findManifestEntryByQualifiedName, getManifest, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, staticManifest };
|
|
45
|
+
export { ManifestBuilder, ManifestGenerator, ManifestManager, SMRT_TEST_MANIFEST_PATHS_ENV_KEY, manifest as default, manifest, discoverManifestEntry, findManifestEntryByQualifiedName, getManifest, isActiveTestManifestPath, isRefusedTestArtifact, isTestArtifactManifest, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, registerActiveTestManifestPath, resolveActiveTestManifestPath, staticManifest };
|
|
45
46
|
|
|
46
47
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/manifest/index.ts"],"sourcesContent":["/**\n * Static manifest module for runtime use\n * Uses pre-generated manifest from build time instead of runtime scanning\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { SmartObjectManifest } from '../scanner/types';\n\n// Re-export utility functions that work with static manifest\nexport { ManifestGenerator } from '../scanner/manifest-generator';\nexport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '../scanner/types';\nexport type { ManifestBuilderOptions } from './generator';\nexport { ManifestBuilder } from './generator';\nexport { ManifestManager } from './manager';\nexport {\n discoverManifestEntry,\n findManifestEntryByQualifiedName,\n loadExternalManifest,\n loadExternalManifestSync,\n loadLocalTestManifestSync,\n loadManifestFromPathSync,\n} from './manifest-loader';\n\nconst EMPTY_STATIC_MANIFEST: SmartObjectManifest = {\n version: '1.0.0',\n timestamp: 0,\n objects: {},\n packageName: '@happyvertical/smrt-core',\n};\n\nfunction loadStaticManifest(): SmartObjectManifest {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const manifestCandidates = [\n join(currentDir, 'static-manifest.json'),\n join(currentDir, '..', 'manifest.json'),\n join(currentDir, '..', '..', 'dist', 'manifest.json'),\n ];\n\n for (const manifestPath of manifestCandidates) {\n if (!existsSync(manifestPath)) {\n continue;\n }\n\n try {\n return JSON.parse(readFileSync(manifestPath, 'utf-8'));\n } catch {\n // Fall through to the next candidate or the empty manifest.\n }\n }\n\n return EMPTY_STATIC_MANIFEST;\n}\n\nexport const manifest = loadStaticManifest();\nexport const staticManifest = manifest;\nexport default manifest;\n\n/**\n * Get manifest data (static at runtime)\n * No longer requires TypeScript compiler or file scanning.\n */\nexport function getManifest() {\n return Promise.resolve(manifest);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/manifest/index.ts"],"sourcesContent":["/**\n * Static manifest module for runtime use\n * Uses pre-generated manifest from build time instead of runtime scanning\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { SmartObjectManifest } from '../scanner/types';\n\n// Re-export utility functions that work with static manifest\nexport { ManifestGenerator } from '../scanner/manifest-generator';\nexport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '../scanner/types';\nexport type { ManifestBuilderOptions } from './generator';\nexport { ManifestBuilder } from './generator';\nexport { ManifestManager } from './manager';\nexport {\n discoverManifestEntry,\n findManifestEntryByQualifiedName,\n loadExternalManifest,\n loadExternalManifestSync,\n loadLocalTestManifestSync,\n loadManifestFromPathSync,\n} from './manifest-loader';\nexport {\n isActiveTestManifestPath,\n isRefusedTestArtifact,\n isTestArtifactManifest,\n registerActiveTestManifestPath,\n resolveActiveTestManifestPath,\n SMRT_TEST_MANIFEST_PATHS_ENV_KEY,\n} from './test-artifacts';\n\nconst EMPTY_STATIC_MANIFEST: SmartObjectManifest = {\n version: '1.0.0',\n timestamp: 0,\n objects: {},\n packageName: '@happyvertical/smrt-core',\n};\n\nfunction loadStaticManifest(): SmartObjectManifest {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const manifestCandidates = [\n join(currentDir, 'static-manifest.json'),\n join(currentDir, '..', 'manifest.json'),\n join(currentDir, '..', '..', 'dist', 'manifest.json'),\n ];\n\n for (const manifestPath of manifestCandidates) {\n if (!existsSync(manifestPath)) {\n continue;\n }\n\n try {\n return JSON.parse(readFileSync(manifestPath, 'utf-8'));\n } catch {\n // Fall through to the next candidate or the empty manifest.\n }\n }\n\n return EMPTY_STATIC_MANIFEST;\n}\n\nexport const manifest = loadStaticManifest();\nexport const staticManifest = manifest;\nexport default manifest;\n\n/**\n * Get manifest data (static at runtime)\n * No longer requires TypeScript compiler or file scanning.\n */\nexport function getManifest() {\n return Promise.resolve(manifest);\n}\n"],"mappings":";;;;;;;;;;;;;AAoCA,IAAM,wBAA6C;CACjD,SAAS;CACT,WAAW;CACX,SAAS,CAAC;CACV,aAAa;AACf;AAEA,SAAS,qBAA0C;CACjD,MAAM,aAAa,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;CACzD,MAAM,qBAAqB;EACzB,KAAK,YAAY,sBAAsB;EACvC,KAAK,YAAY,MAAM,eAAe;EACtC,KAAK,YAAY,MAAM,MAAM,QAAQ,eAAe;CACtD;CAEA,KAAK,MAAM,gBAAgB,oBAAoB;EAC7C,IAAI,CAAC,WAAW,YAAY,GAC1B;EAGF,IAAI;GACF,OAAO,KAAK,MAAM,aAAa,cAAc,OAAO,CAAC;EACvD,QAAQ,CAER;CACF;CAEA,OAAO;AACT;AAEA,IAAa,WAAW,mBAAmB;AAC3C,IAAa,iBAAiB;;;;;AAO9B,SAAgB,cAAc;CAC5B,OAAO,QAAQ,QAAQ,QAAQ;AACjC"}
|
|
@@ -19,6 +19,12 @@ export interface ManifestFileAccess {
|
|
|
19
19
|
* `src/manifest/manifest.json`. When loading a local project, the dev path takes
|
|
20
20
|
* priority; for external packages (dependencies), the build path takes priority
|
|
21
21
|
* to avoid pulling in test objects.
|
|
22
|
+
*
|
|
23
|
+
* Inside a test run, the run's active test manifest snapshot (see
|
|
24
|
+
* `test-artifacts.ts`, #4128) precedes every local path. A manifest marked
|
|
25
|
+
* `artifactPurpose: 'test'` found anywhere else is skipped (#2760). It is never written
|
|
26
|
+
* to, or read from, the standard locations, so a concurrent build cannot
|
|
27
|
+
* replace it and a process outside the run never reads it.
|
|
22
28
|
*/
|
|
23
29
|
export declare class LocalManifestReader {
|
|
24
30
|
protected projectRoot: string;
|
|
@@ -29,8 +35,13 @@ export declare class LocalManifestReader {
|
|
|
29
35
|
*/
|
|
30
36
|
getOutputPath(mode: 'dev' | 'build' | 'source'): string;
|
|
31
37
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
38
|
+
* The paths {@link loadLocal} reads, in priority order: the active test
|
|
39
|
+
* manifest snapshot (only inside a test run that registered one), then
|
|
40
|
+
* `.smrt/manifest.json`, `dist/manifest.json`, `src/manifest/manifest.json`.
|
|
41
|
+
*/
|
|
42
|
+
getLocalCandidatePaths(): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Loads the local manifest from {@link getLocalCandidatePaths}.
|
|
34
45
|
*/
|
|
35
46
|
loadLocal(): SmartObjectManifest | null;
|
|
36
47
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-manifest-reader.d.ts","sourceRoot":"","sources":["../../src/manifest/local-manifest-reader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"local-manifest-reader.d.ts","sourceRoot":"","sources":["../../src/manifest/local-manifest-reader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAO/D,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;CACvD;AAaD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,mBAAmB;IAE5B,SAAS,CAAC,WAAW,EAAE,MAAM;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADZ,WAAW,EAAE,MAAM,EACZ,KAAK,GAAE,kBAAmC;IAG7D;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM;IAUvD;;;;OAIG;IACH,sBAAsB,IAAI,MAAM,EAAE;IAsBlC;;OAEG;IACH,SAAS,IAAI,mBAAmB,GAAG,IAAI;IAIvC;;;;;;;;OAQG;IACH,sBAAsB,IAAI,mBAAmB,GAAG,IAAI;IAQpD,OAAO,CAAC,cAAc;CA4BvB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRefusedTestArtifact, resolveActiveTestManifestPath } from "./test-artifacts.js";
|
|
1
2
|
import { existsSync, join, readFileSync } from "./node-host.js";
|
|
2
3
|
import { createLogger } from "@happyvertical/logger";
|
|
3
4
|
//#region src/manifest/local-manifest-reader.ts
|
|
@@ -7,6 +8,10 @@ var hostFileAccess = {
|
|
|
7
8
|
readFileSync
|
|
8
9
|
};
|
|
9
10
|
var logger = createLogger({ level: "info" });
|
|
11
|
+
/** Registered test snapshots already reported missing, so each warns once. */
|
|
12
|
+
var reportedMissingTestManifests = /* @__PURE__ */ new Set();
|
|
13
|
+
/** Refused test artifacts already reported, so each warns once. */
|
|
14
|
+
var reportedRefusedTestArtifacts = /* @__PURE__ */ new Set();
|
|
10
15
|
/**
|
|
11
16
|
* Reads SMRT manifests for a project from the standard locations.
|
|
12
17
|
*
|
|
@@ -22,6 +27,12 @@ var logger = createLogger({ level: "info" });
|
|
|
22
27
|
* `src/manifest/manifest.json`. When loading a local project, the dev path takes
|
|
23
28
|
* priority; for external packages (dependencies), the build path takes priority
|
|
24
29
|
* to avoid pulling in test objects.
|
|
30
|
+
*
|
|
31
|
+
* Inside a test run, the run's active test manifest snapshot (see
|
|
32
|
+
* `test-artifacts.ts`, #4128) precedes every local path. A manifest marked
|
|
33
|
+
* `artifactPurpose: 'test'` found anywhere else is skipped (#2760). It is never written
|
|
34
|
+
* to, or read from, the standard locations, so a concurrent build cannot
|
|
35
|
+
* replace it and a process outside the run never reads it.
|
|
25
36
|
*/
|
|
26
37
|
var LocalManifestReader = class {
|
|
27
38
|
projectRoot;
|
|
@@ -39,15 +50,28 @@ var LocalManifestReader = class {
|
|
|
39
50
|
return join(this.projectRoot, "dist/manifest.json");
|
|
40
51
|
}
|
|
41
52
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
53
|
+
* The paths {@link loadLocal} reads, in priority order: the active test
|
|
54
|
+
* manifest snapshot (only inside a test run that registered one), then
|
|
55
|
+
* `.smrt/manifest.json`, `dist/manifest.json`, `src/manifest/manifest.json`.
|
|
44
56
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
57
|
+
getLocalCandidatePaths() {
|
|
58
|
+
const activeTestManifest = resolveActiveTestManifestPath(this.projectRoot);
|
|
59
|
+
if (activeTestManifest && !this.files.existsSync(activeTestManifest) && !reportedMissingTestManifests.has(activeTestManifest)) {
|
|
60
|
+
reportedMissingTestManifests.add(activeTestManifest);
|
|
61
|
+
logger.warn(`[ManifestManager] The active test manifest ${activeTestManifest} registered for ${this.projectRoot} is missing; falling back to production manifests, so inline test fixtures are not described`);
|
|
62
|
+
}
|
|
63
|
+
return [
|
|
64
|
+
...activeTestManifest ? [activeTestManifest] : [],
|
|
47
65
|
this.getOutputPath("dev"),
|
|
48
66
|
this.getOutputPath("build"),
|
|
49
67
|
this.getOutputPath("source")
|
|
50
|
-
]
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Loads the local manifest from {@link getLocalCandidatePaths}.
|
|
72
|
+
*/
|
|
73
|
+
loadLocal() {
|
|
74
|
+
return this._loadFromPaths(this.getLocalCandidatePaths());
|
|
51
75
|
}
|
|
52
76
|
/**
|
|
53
77
|
* Loads the manifest for an external package (dependency).
|
|
@@ -68,7 +92,15 @@ var LocalManifestReader = class {
|
|
|
68
92
|
_loadFromPaths(paths) {
|
|
69
93
|
for (const path of paths) if (this.files.existsSync(path)) try {
|
|
70
94
|
const content = this.files.readFileSync(path, "utf-8");
|
|
71
|
-
|
|
95
|
+
const manifest = JSON.parse(content);
|
|
96
|
+
if (isRefusedTestArtifact(manifest, path)) {
|
|
97
|
+
if (!reportedRefusedTestArtifacts.has(path)) {
|
|
98
|
+
reportedRefusedTestArtifacts.add(path);
|
|
99
|
+
logger.warn(`[ManifestManager] Skipping test artifact at ${path}: a test run's manifest is not a build output, and this process is not that run (rebuild to replace it)`);
|
|
100
|
+
}
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
return manifest;
|
|
72
104
|
} catch (error) {
|
|
73
105
|
logger.error(`[ManifestManager] Failed to read manifest at ${path}`, { error });
|
|
74
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-manifest-reader.js","names":[],"sources":["../../src/manifest/local-manifest-reader.ts"],"sourcesContent":["import { createLogger } from '@happyvertical/logger';\nimport type { SmartObjectManifest } from '../scanner/types.js';\nimport { existsSync, join, readFileSync } from './node-host.js';\n\n/** The two filesystem reads a manifest load needs. */\nexport interface ManifestFileAccess {\n existsSync(path: string): boolean;\n readFileSync(path: string, encoding: 'utf-8'): string;\n}\n\n/** Resolved through the lazy Node host: absent files on a host without one. */\nconst hostFileAccess: ManifestFileAccess = { existsSync, readFileSync };\n\nconst logger = createLogger({ level: 'info' });\n\n/**\n * Reads SMRT manifests for a project from the standard locations.\n *\n * @remarks\n * The read half of `ManifestManager`, split out so the registry's manifest\n * discovery does not pull the write and generation half (`node:fs` writes,\n * the AST scanner) into a browser bundle (#2838). Filesystem access goes\n * through `node-host.ts`, so without a Node host every load finds nothing.\n *\n * Manifests are JSON files containing class/field metadata produced by the AST scanner.\n * Dev manifests live at `.smrt/manifest.json`; build manifests at `dist/manifest.json`.\n * Workspace packages may also provide a checked-in source manifest at\n * `src/manifest/manifest.json`. When loading a local project, the dev path takes\n * priority; for external packages (dependencies), the build path takes priority\n * to avoid pulling in test objects.\n */\nexport class LocalManifestReader {\n constructor(\n protected projectRoot: string,\n private readonly files: ManifestFileAccess = hostFileAccess,\n ) {}\n\n /**\n * Get the standard output path for the manifest based on mode.\n */\n getOutputPath(mode: 'dev' | 'build' | 'source'): string {\n if (mode === 'dev') {\n return join(this.projectRoot, '.smrt/manifest.json');\n }\n if (mode === 'source') {\n return join(this.projectRoot, 'src/manifest/manifest.json');\n }\n return join(this.projectRoot, 'dist/manifest.json');\n }\n\n /**\n *
|
|
1
|
+
{"version":3,"file":"local-manifest-reader.js","names":[],"sources":["../../src/manifest/local-manifest-reader.ts"],"sourcesContent":["import { createLogger } from '@happyvertical/logger';\nimport type { SmartObjectManifest } from '../scanner/types.js';\nimport { existsSync, join, readFileSync } from './node-host.js';\nimport {\n isRefusedTestArtifact,\n resolveActiveTestManifestPath,\n} from './test-artifacts.js';\n\n/** The two filesystem reads a manifest load needs. */\nexport interface ManifestFileAccess {\n existsSync(path: string): boolean;\n readFileSync(path: string, encoding: 'utf-8'): string;\n}\n\n/** Resolved through the lazy Node host: absent files on a host without one. */\nconst hostFileAccess: ManifestFileAccess = { existsSync, readFileSync };\n\nconst logger = createLogger({ level: 'info' });\n\n/** Registered test snapshots already reported missing, so each warns once. */\nconst reportedMissingTestManifests = new Set<string>();\n\n/** Refused test artifacts already reported, so each warns once. */\nconst reportedRefusedTestArtifacts = new Set<string>();\n\n/**\n * Reads SMRT manifests for a project from the standard locations.\n *\n * @remarks\n * The read half of `ManifestManager`, split out so the registry's manifest\n * discovery does not pull the write and generation half (`node:fs` writes,\n * the AST scanner) into a browser bundle (#2838). Filesystem access goes\n * through `node-host.ts`, so without a Node host every load finds nothing.\n *\n * Manifests are JSON files containing class/field metadata produced by the AST scanner.\n * Dev manifests live at `.smrt/manifest.json`; build manifests at `dist/manifest.json`.\n * Workspace packages may also provide a checked-in source manifest at\n * `src/manifest/manifest.json`. When loading a local project, the dev path takes\n * priority; for external packages (dependencies), the build path takes priority\n * to avoid pulling in test objects.\n *\n * Inside a test run, the run's active test manifest snapshot (see\n * `test-artifacts.ts`, #4128) precedes every local path. A manifest marked\n * `artifactPurpose: 'test'` found anywhere else is skipped (#2760). It is never written\n * to, or read from, the standard locations, so a concurrent build cannot\n * replace it and a process outside the run never reads it.\n */\nexport class LocalManifestReader {\n constructor(\n protected projectRoot: string,\n private readonly files: ManifestFileAccess = hostFileAccess,\n ) {}\n\n /**\n * Get the standard output path for the manifest based on mode.\n */\n getOutputPath(mode: 'dev' | 'build' | 'source'): string {\n if (mode === 'dev') {\n return join(this.projectRoot, '.smrt/manifest.json');\n }\n if (mode === 'source') {\n return join(this.projectRoot, 'src/manifest/manifest.json');\n }\n return join(this.projectRoot, 'dist/manifest.json');\n }\n\n /**\n * The paths {@link loadLocal} reads, in priority order: the active test\n * manifest snapshot (only inside a test run that registered one), then\n * `.smrt/manifest.json`, `dist/manifest.json`, `src/manifest/manifest.json`.\n */\n getLocalCandidatePaths(): string[] {\n const activeTestManifest = resolveActiveTestManifestPath(this.projectRoot);\n if (\n activeTestManifest &&\n !this.files.existsSync(activeTestManifest) &&\n !reportedMissingTestManifests.has(activeTestManifest)\n ) {\n // Falling through to the production chain silently would reproduce\n // the #4128 symptom (fixture metadata vanishing) with no signal.\n reportedMissingTestManifests.add(activeTestManifest);\n logger.warn(\n `[ManifestManager] The active test manifest ${activeTestManifest} registered for ${this.projectRoot} is missing; falling back to production manifests, so inline test fixtures are not described`,\n );\n }\n return [\n ...(activeTestManifest ? [activeTestManifest] : []),\n this.getOutputPath('dev'),\n this.getOutputPath('build'),\n this.getOutputPath('source'),\n ];\n }\n\n /**\n * Loads the local manifest from {@link getLocalCandidatePaths}.\n */\n loadLocal(): SmartObjectManifest | null {\n return this._loadFromPaths(this.getLocalCandidatePaths());\n }\n\n /**\n * Loads the manifest for an external package (dependency).\n * Priority: dist/manifest.json -> .smrt/manifest.json -> src/manifest/manifest.json\n *\n * External packages should prefer their production (dist) manifest\n * over the dev/test (.smrt) manifest to avoid pulling in test objects\n * and transitive dependencies. In a workspace, the checked-in source manifest\n * provides the same package metadata even when the sibling package has not been built yet.\n */\n loadForExternalPackage(): SmartObjectManifest | null {\n return this._loadFromPaths([\n this.getOutputPath('build'),\n this.getOutputPath('dev'),\n this.getOutputPath('source'),\n ]);\n }\n\n private _loadFromPaths(paths: string[]): SmartObjectManifest | null {\n for (const path of paths) {\n if (this.files.existsSync(path)) {\n try {\n const content = this.files.readFileSync(path, 'utf-8');\n const manifest = JSON.parse(content);\n // A test artifact is only valid as its own run's active snapshot;\n // anywhere else its inline fixtures are phantom objects (#2760).\n if (isRefusedTestArtifact(manifest, path)) {\n if (!reportedRefusedTestArtifacts.has(path)) {\n reportedRefusedTestArtifacts.add(path);\n logger.warn(\n `[ManifestManager] Skipping test artifact at ${path}: a test run's manifest is not a build output, and this process is not that run (rebuild to replace it)`,\n );\n }\n continue;\n }\n return manifest;\n } catch (error) {\n logger.error(`[ManifestManager] Failed to read manifest at ${path}`, {\n error,\n });\n }\n }\n }\n\n return null;\n }\n}\n"],"mappings":";;;;;AAeA,IAAM,iBAAqC;CAAE;CAAY;AAAa;AAEtE,IAAM,SAAS,aAAa,EAAE,OAAO,OAAO,CAAC;;AAG7C,IAAM,+CAA+B,IAAI,IAAY;;AAGrD,IAAM,+CAA+B,IAAI,IAAY;;;;;;;;;;;;;;;;;;;;;;;AAwBrD,IAAa,sBAAb,MAAiC;CAEnB;CACO;CAFnB,YACE,aACA,QAA6C,gBAC7C;EAFU,KAAA,cAAA;EACO,KAAA,QAAA;CAChB;;;;CAKH,cAAc,MAA0C;EACtD,IAAI,SAAS,OACX,OAAO,KAAK,KAAK,aAAa,qBAAqB;EAErD,IAAI,SAAS,UACX,OAAO,KAAK,KAAK,aAAa,4BAA4B;EAE5D,OAAO,KAAK,KAAK,aAAa,oBAAoB;CACpD;;;;;;CAOA,yBAAmC;EACjC,MAAM,qBAAqB,8BAA8B,KAAK,WAAW;EACzE,IACE,sBACA,CAAC,KAAK,MAAM,WAAW,kBAAkB,KACzC,CAAC,6BAA6B,IAAI,kBAAkB,GACpD;GAGA,6BAA6B,IAAI,kBAAkB;GACnD,OAAO,KACL,8CAA8C,mBAAmB,kBAAkB,KAAK,YAAY,6FACtG;EACF;EACA,OAAO;GACL,GAAI,qBAAqB,CAAC,kBAAkB,IAAI,CAAC;GACjD,KAAK,cAAc,KAAK;GACxB,KAAK,cAAc,OAAO;GAC1B,KAAK,cAAc,QAAQ;EAC7B;CACF;;;;CAKA,YAAwC;EACtC,OAAO,KAAK,eAAe,KAAK,uBAAuB,CAAC;CAC1D;;;;;;;;;;CAWA,yBAAqD;EACnD,OAAO,KAAK,eAAe;GACzB,KAAK,cAAc,OAAO;GAC1B,KAAK,cAAc,KAAK;GACxB,KAAK,cAAc,QAAQ;EAC7B,CAAC;CACH;CAEA,eAAuB,OAA6C;EAClE,KAAK,MAAM,QAAQ,OACjB,IAAI,KAAK,MAAM,WAAW,IAAI,GAC5B,IAAI;GACF,MAAM,UAAU,KAAK,MAAM,aAAa,MAAM,OAAO;GACrD,MAAM,WAAW,KAAK,MAAM,OAAO;GAGnC,IAAI,sBAAsB,UAAU,IAAI,GAAG;IACzC,IAAI,CAAC,6BAA6B,IAAI,IAAI,GAAG;KAC3C,6BAA6B,IAAI,IAAI;KACrC,OAAO,KACL,+CAA+C,KAAK,wGACtD;IACF;IACA;GACF;GACA,OAAO;EACT,SAAS,OAAO;GACd,OAAO,MAAM,gDAAgD,QAAQ,EACnE,MACF,CAAC;EACH;EAIJ,OAAO;CACT;AACF"}
|
|
@@ -65,14 +65,15 @@ export type { FieldDefinition, MethodDefinition };
|
|
|
65
65
|
export declare function loadLocalTestManifestSync(): Manifest | null | undefined;
|
|
66
66
|
/**
|
|
67
67
|
* The manifest of the project the process runs in (the first of
|
|
68
|
-
*
|
|
69
|
-
* `<cwd
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
68
|
+
* `LocalManifestReader.getLocalCandidatePaths()`: a test run's active
|
|
69
|
+
* snapshot, then `<cwd>/.smrt/manifest.json`, `<cwd>/dist/manifest.json`,
|
|
70
|
+
* `<cwd>/src/manifest/manifest.json`, skipping a test artifact outside its
|
|
71
|
+
* own run, #2760), never seeded into the lookup caches. Only consulted to
|
|
72
|
+
* attribute a decorated class whose declaring file that manifest describes,
|
|
73
|
+
* when no loaded manifest does: a plain Node/tsx script importing an app's
|
|
74
|
+
* workspace-package models has not loaded the app's manifest yet (#3109).
|
|
75
|
+
* Each read is reused only while that file is unchanged, so a dev server that
|
|
76
|
+
* regenerates it is seen; a missing manifest is never cached.
|
|
76
77
|
*/
|
|
77
78
|
export declare function readProjectManifestSync(): SmartObjectManifest | null;
|
|
78
79
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../../src/manifest/manifest-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../../src/manifest/manifest-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { bumpRegistryGeneration } from "../registry/generation.js";
|
|
|
3
3
|
import "../scanner/types.js";
|
|
4
4
|
import { parse } from "../utils/json.js";
|
|
5
5
|
import { isDecoratorRuntimeFramePath, isDecoratorRuntimePackageName, isModuleRunnerFramePath, isSmrtCoreFramePath } from "../utils/stack-frames.js";
|
|
6
|
+
import { isRefusedTestArtifact } from "./test-artifacts.js";
|
|
6
7
|
import { getLocalTestManifestCache as getLocalTestManifestCache$1, getManifestCache, getStaticManifestCache as getStaticManifestCache$1, getTestManifestCache as getTestManifestCache$1, isTestEnvironment as isTestEnvironment$1, shouldLoadCoreTestManifest } from "./store.js";
|
|
7
8
|
import { dirname, existsSync, join, readFileSync, readdirSync, require, statSync } from "./node-host.js";
|
|
8
9
|
import { LocalManifestReader } from "./local-manifest-reader.js";
|
|
@@ -207,7 +208,9 @@ function loadLocalTestManifestSync() {
|
|
|
207
208
|
if (existsSync(testManifestPath)) try {
|
|
208
209
|
const testManifest = parse(readFileSync(testManifestPath, "utf-8"));
|
|
209
210
|
const testObjectCount = Object.keys(testManifest.objects).length;
|
|
210
|
-
|
|
211
|
+
const refused = isRefusedTestArtifact(testManifest, testManifestPath);
|
|
212
|
+
if (refused && testObjectCount > 0) warnRefusedLocalTestManifest(testManifestPath);
|
|
213
|
+
if (testObjectCount > 0 && !refused) {
|
|
211
214
|
setLocalTestManifestCache(testManifest);
|
|
212
215
|
debugLog(`[manifest-loader] ✅ Loaded test manifest from ${testManifestPath} (${testObjectCount} objects) - preferred over empty LocalManifestReader result`);
|
|
213
216
|
return testManifest;
|
|
@@ -219,6 +222,10 @@ function loadLocalTestManifestSync() {
|
|
|
219
222
|
}
|
|
220
223
|
if (existsSync(testManifestPath)) try {
|
|
221
224
|
const testManifest = parse(readFileSync(testManifestPath, "utf-8"));
|
|
225
|
+
if (isRefusedTestArtifact(testManifest, testManifestPath)) {
|
|
226
|
+
warnRefusedLocalTestManifest(testManifestPath);
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
222
229
|
setLocalTestManifestCache(testManifest);
|
|
223
230
|
const objectCount = Object.keys(testManifest.objects).length;
|
|
224
231
|
debugLog(`[manifest-loader] ✅ Loaded test manifest from ${testManifestPath} (${objectCount} objects)`);
|
|
@@ -229,48 +236,65 @@ function loadLocalTestManifestSync() {
|
|
|
229
236
|
debugLog("[manifest-loader] ⚠️ No local manifest found (will retry on next call)");
|
|
230
237
|
return null;
|
|
231
238
|
}
|
|
232
|
-
var
|
|
239
|
+
var warnedRefusedLocalTestManifests = /* @__PURE__ */ new Set();
|
|
233
240
|
/**
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
* them), never seeded into the lookup caches. Only consulted to attribute a
|
|
238
|
-
* decorated class whose declaring file that manifest describes, when no loaded
|
|
239
|
-
* manifest does: a plain Node/tsx script importing an app's workspace-package
|
|
240
|
-
* models has not loaded the app's manifest yet (#3109). The read is reused
|
|
241
|
-
* only while that file is unchanged, so a dev server that regenerates it is
|
|
242
|
-
* seen; a missing manifest is never cached.
|
|
241
|
+
* Warn once that a local test manifest was refused: outside the test run that
|
|
242
|
+
* registered it, its inline fixtures would be phantom objects (#2760), and
|
|
243
|
+
* inside an unregistered run their metadata is silently missing otherwise.
|
|
243
244
|
*/
|
|
244
|
-
function
|
|
245
|
-
if (
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
if (!path) return null;
|
|
245
|
+
function warnRefusedLocalTestManifest(path) {
|
|
246
|
+
if (warnedRefusedLocalTestManifests.has(path)) return;
|
|
247
|
+
warnedRefusedLocalTestManifests.add(path);
|
|
248
|
+
logger.warn(`[manifest-loader] Ignoring test manifest ${path}: it is not this process's active test manifest. Run tests under smrtVitestPlugin() (or register it with registerActiveTestManifestPath()) to use it.`);
|
|
249
|
+
}
|
|
250
|
+
var projectManifestReads = /* @__PURE__ */ new Map();
|
|
251
|
+
/** Parse `path`, reusing the previous parse while its mtime is unchanged. */
|
|
252
|
+
function readProjectManifestCandidate(path) {
|
|
253
253
|
let mtimeMs;
|
|
254
254
|
try {
|
|
255
255
|
mtimeMs = statSync(path).mtimeMs;
|
|
256
256
|
} catch {
|
|
257
|
-
return
|
|
257
|
+
return;
|
|
258
258
|
}
|
|
259
|
-
|
|
259
|
+
const cached = projectManifestReads.get(path);
|
|
260
|
+
if (cached?.mtimeMs === mtimeMs) return cached.manifest;
|
|
260
261
|
let manifest = null;
|
|
261
262
|
try {
|
|
262
263
|
manifest = parse(readFileSync(path, "utf-8"));
|
|
263
264
|
} catch {
|
|
264
265
|
manifest = null;
|
|
265
266
|
}
|
|
266
|
-
|
|
267
|
-
path,
|
|
267
|
+
projectManifestReads.set(path, {
|
|
268
268
|
mtimeMs,
|
|
269
269
|
manifest
|
|
270
|
-
};
|
|
270
|
+
});
|
|
271
271
|
return manifest;
|
|
272
272
|
}
|
|
273
273
|
/**
|
|
274
|
+
* The manifest of the project the process runs in (the first of
|
|
275
|
+
* `LocalManifestReader.getLocalCandidatePaths()`: a test run's active
|
|
276
|
+
* snapshot, then `<cwd>/.smrt/manifest.json`, `<cwd>/dist/manifest.json`,
|
|
277
|
+
* `<cwd>/src/manifest/manifest.json`, skipping a test artifact outside its
|
|
278
|
+
* own run, #2760), never seeded into the lookup caches. Only consulted to
|
|
279
|
+
* attribute a decorated class whose declaring file that manifest describes,
|
|
280
|
+
* when no loaded manifest does: a plain Node/tsx script importing an app's
|
|
281
|
+
* workspace-package models has not loaded the app's manifest yet (#3109).
|
|
282
|
+
* Each read is reused only while that file is unchanged, so a dev server that
|
|
283
|
+
* regenerates it is seen; a missing manifest is never cached.
|
|
284
|
+
*/
|
|
285
|
+
function readProjectManifestSync() {
|
|
286
|
+
if (typeof process === "undefined" || typeof process.cwd !== "function") return null;
|
|
287
|
+
const manager = new LocalManifestReader(process.cwd());
|
|
288
|
+
for (const candidate of manager.getLocalCandidatePaths()) {
|
|
289
|
+
if (!existsSync(candidate)) continue;
|
|
290
|
+
const manifest = readProjectManifestCandidate(candidate);
|
|
291
|
+
if (manifest === void 0) return null;
|
|
292
|
+
if (isRefusedTestArtifact(manifest, candidate)) continue;
|
|
293
|
+
return manifest;
|
|
294
|
+
}
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
274
298
|
* Extract package name from class constructor
|
|
275
299
|
*
|
|
276
300
|
* Uses the ObjectRegistry (preferred) or fallback methods to determine
|
|
@@ -379,9 +403,17 @@ function resolveWorkspacePackageJsonPath(packageName) {
|
|
|
379
403
|
}
|
|
380
404
|
return null;
|
|
381
405
|
}
|
|
406
|
+
/** Whether the manifest file at `path` is a refused test artifact (#2760). */
|
|
407
|
+
function isRefusedTestArtifactFile(path) {
|
|
408
|
+
try {
|
|
409
|
+
return isRefusedTestArtifact(parse(readFileSync(path, "utf-8")), path);
|
|
410
|
+
} catch {
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
382
414
|
function resolveWorkspaceSourceManifestPath(packageDir) {
|
|
383
415
|
const candidates = [join(packageDir, "src", "manifest", "manifest.json"), join(packageDir, ".smrt", "manifest.json")];
|
|
384
|
-
for (const candidate of candidates) if (existsSync(candidate)) return candidate;
|
|
416
|
+
for (const candidate of candidates) if (existsSync(candidate) && !isRefusedTestArtifactFile(candidate)) return candidate;
|
|
385
417
|
return null;
|
|
386
418
|
}
|
|
387
419
|
function resolveManifestExportPath(packageName, options = {}) {
|
|
@@ -450,6 +482,10 @@ function loadExternalManifestSync(packageName, options = {}) {
|
|
|
450
482
|
if (options.warn ?? true) logger.warn(`Invalid manifest structure for package ${packageName}`);
|
|
451
483
|
return null;
|
|
452
484
|
}
|
|
485
|
+
if (isRefusedTestArtifact(manifest, manifestPath)) {
|
|
486
|
+
if (options.warn ?? true) logger.warn(`Ignoring test artifact ${manifestPath} for package ${packageName}; test manifests are never dependency manifests`);
|
|
487
|
+
return null;
|
|
488
|
+
}
|
|
453
489
|
const cachedManifest = manifest.packageName ? manifest : {
|
|
454
490
|
...manifest,
|
|
455
491
|
packageName
|
|
@@ -479,6 +515,10 @@ function loadManifestFromPathSync(manifestPath) {
|
|
|
479
515
|
logger.warn(`Invalid manifest structure at ${manifestPath}`);
|
|
480
516
|
return null;
|
|
481
517
|
}
|
|
518
|
+
if (isRefusedTestArtifact(manifest, manifestPath)) {
|
|
519
|
+
logger.warn(`Ignoring test artifact ${manifestPath}; it is not this process's active test manifest`);
|
|
520
|
+
return null;
|
|
521
|
+
}
|
|
482
522
|
const cacheKey = manifest.packageName || manifestPath;
|
|
483
523
|
getManifestCacheMap().set(cacheKey, manifest);
|
|
484
524
|
debugLog(`[manifest-loader] ✅ Loaded manifest from path ${manifestPath} (${Object.keys(manifest.objects).length} objects)`);
|
|
@@ -756,7 +796,7 @@ function clearManifestCache() {
|
|
|
756
796
|
getManifestCacheMap().clear();
|
|
757
797
|
getManifestCollisionsMap().clear();
|
|
758
798
|
getSTISiblingCache().clear();
|
|
759
|
-
|
|
799
|
+
projectManifestReads.clear();
|
|
760
800
|
}
|
|
761
801
|
/**
|
|
762
802
|
* Get all loaded manifests
|