@_linked/cli 1.45.1 → 1.45.3
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/CHANGELOG.md +12 -0
- package/README.md +4 -3
- package/lib/esm/app-release/publisher.d.ts.map +1 -1
- package/lib/esm/app-release/publisher.js +4 -3
- package/lib/esm/app-release/publisher.js.map +1 -1
- package/lib/esm/launch.js +6 -3
- package/lib/esm/launch.js.map +1 -1
- package/lib/esm/lifecycle.d.ts.map +1 -1
- package/lib/esm/lifecycle.js +2 -7
- package/lib/esm/lifecycle.js.map +1 -1
- package/lib/esm/loader-mode.d.ts +37 -0
- package/lib/esm/loader-mode.d.ts.map +1 -0
- package/lib/esm/loader-mode.js +100 -0
- package/lib/esm/loader-mode.js.map +1 -0
- package/lib/esm/loaders/css-loader.d.mts +4 -0
- package/lib/esm/loaders/css-loader.d.mts.map +1 -1
- package/lib/esm/loaders/css-loader.mjs +25 -1
- package/lib/esm/loaders/css-loader.mjs.map +1 -1
- package/lib/esm/loaders/register.d.ts +14 -0
- package/lib/esm/loaders/register.d.ts.map +1 -0
- package/lib/esm/loaders/register.js +23 -0
- package/lib/esm/loaders/register.js.map +1 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.45.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#132](https://github.com/linked-fw/cli/pull/132) [`283e7ad`](https://github.com/linked-fw/cli/commit/283e7adfaa9f10bbf6c1d4ca90a9b708542c576b) Thanks [@abdipramana](https://github.com/abdipramana)! - Preserve validated release object paths exactly when publishing app artifacts, preventing file-store sanitization from breaking the URLs embedded in production bundles.
|
|
8
|
+
|
|
9
|
+
## 1.45.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#214](https://github.com/linked-fw/cli/pull/214) [`684cd26`](https://github.com/linked-fw/cli/commit/684cd26d626e63b42bd1b4b5aff0f35955cdc47e) Thanks [@carlenmy](https://github.com/carlenmy)! - The Node CSS loader now names package stylesheets in the mode the app actually runs in. It runs on Node's module-hooks thread, which copies `process.env` when `launch.js` registers it, before the CLI loads the app's `.env`. So a `NODE_ENV=development` that came only from `.env` (or `.env-cmdrc.json`) never reached it, and externalised packages such as `@_linked/primitives` were server-rendered with production class names while the dev client used dev names, which caused a hydration mismatch. `launch.js` now resolves the mode before registering the hooks (shell, then `.env`, then the `.env-cmdrc.json` profile, then `development` for `linked start`) and passes it to the loader through `register(url, {data})`. Production naming is unchanged.
|
|
14
|
+
|
|
3
15
|
## 1.45.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -195,9 +195,10 @@ release is never marked complete, and re-running `publish-app` resumes it.
|
|
|
195
195
|
|
|
196
196
|
**The store must keep keys verbatim.** A release object has to be stored under exactly the key it
|
|
197
197
|
was given, or the URLs baked into the bundle point at nothing, so publishing passes
|
|
198
|
-
`preventDuplicates: false` and
|
|
199
|
-
|
|
200
|
-
|
|
198
|
+
`preventDuplicates: false` and `preservePath: true`. A compatible store preserves the safe relative
|
|
199
|
+
key exactly and rejects absolute or traversal paths. Publishing fails with a clear message if the
|
|
200
|
+
store reports a different location. `@_linked/server`'s `LocalFileStore` supports this contract;
|
|
201
|
+
stores that do not support exact keys cannot publish a linked release.
|
|
201
202
|
|
|
202
203
|
**Cache policy follows the origin, not the filename.** Files listed in the Vite manifest are
|
|
203
204
|
content-hashed by construction and get `public, max-age=31536000, immutable`. Everything else —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publisher.d.ts","sourceRoot":"","sources":["../../../src/app-release/publisher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,qCAAqC,CAAC;AASpE,OAAO,KAAK,EAEV,wBAAwB,EACxB,WAAW,EACX,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,wBAAwB,CAAC;CACpC;AAED,MAAM,WAAW,qBAAsB,SAAQ,yBAAyB;IACtE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;IACjD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAkCD,eAAO,MAAM,mBAAmB,GAC9B,SAAS,MAAM,EACf,qBAAmC,KAClC,qBA6BF,CAAC;AA2CF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,yBAAyB,KACjC,WAsBF,CAAC;AAkCF,eAAO,MAAM,cAAc,GACzB,SAAS,qBAAqB,KAC7B,OAAO,CAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"publisher.d.ts","sourceRoot":"","sources":["../../../src/app-release/publisher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,qCAAqC,CAAC;AASpE,OAAO,KAAK,EAEV,wBAAwB,EACxB,WAAW,EACX,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,wBAAwB,CAAC;CACpC;AAED,MAAM,WAAW,qBAAsB,SAAQ,yBAAyB;IACtE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;IACjD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAkCD,eAAO,MAAM,mBAAmB,GAC9B,SAAS,MAAM,EACf,qBAAmC,KAClC,qBA6BF,CAAC;AA2CF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,yBAAyB,KACjC,WAsBF,CAAC;AAkCF,eAAO,MAAM,cAAc,GACzB,SAAS,qBAAqB,KAC7B,OAAO,CAAC,aAAa,CAiJvB,CAAC"}
|
|
@@ -147,13 +147,14 @@ export const publishRelease = (options) => __awaiter(void 0, void 0, void 0, fun
|
|
|
147
147
|
'checked against the manifest before upload; the remote copy is not re-checked.');
|
|
148
148
|
};
|
|
149
149
|
const upload = (objectKey, content, contentType, cacheControl, sha256) => __awaiter(void 0, void 0, void 0, function* () {
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
150
|
+
// A release key must be exactly the key in the manifest. Disable duplicate
|
|
151
|
+
// renaming and ask the store to preserve the validated relative path; any
|
|
152
|
+
// suffix or sanitisation would break the URL and make verification useless.
|
|
153
153
|
const storedURL = yield options.store.saveFile(objectKey, content, {
|
|
154
154
|
mimeType: contentType,
|
|
155
155
|
cacheControl,
|
|
156
156
|
preventDuplicates: false,
|
|
157
|
+
preservePath: true,
|
|
157
158
|
});
|
|
158
159
|
// A release key has to survive the round trip verbatim, or the published
|
|
159
160
|
// URLs in the bundle point at nothing. Some stores sanitise or suffix the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../../src/app-release/publisher.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from 'crypto';\nimport fs from 'fs';\nimport type {IFileStore} from '@_linked/core/interfaces/IFileStore';\nimport {normalizeAccessURL} from './app-assets-store.js';\nimport {\n MANIFEST_CONTENT_TYPE,\n MANIFEST_SOURCE_PATH,\n ENTRY_CACHE_CONTROL,\n releaseObjectKey,\n} from './create-release-manifest.js';\nimport {normalizeReleasePath, resolveExistingPathWithinRoot} from './paths.js';\nimport type {\n LinkedAppReleaseFile,\n LinkedAppReleaseManifest,\n PublishPlan,\n PublishResult,\n} from './types.js';\n\nexport interface PlanReleasePublishOptions {\n appRoot: string;\n manifestPath?: string;\n store: IFileStore;\n}\n\nexport interface LoadedReleaseManifest {\n absolutePath: string;\n manifest: LinkedAppReleaseManifest;\n}\n\nexport interface PublishReleaseOptions extends PlanReleasePublishOptions {\n yes?: boolean;\n onProgress?: (progress: PublishProgress) => void;\n onWarning?: (message: string) => void;\n}\n\nexport interface PublishProgress {\n completed: number;\n total: number;\n objectKey: string;\n}\n\n/**\n * Every object of a release must land under that release's own prefix.\n *\n * The manifest is a plain file on disk: a hand-edited or foreign one can name\n * any `objectKey` it likes, and nothing else catches it — the `accessURL` check\n * only proves the store is the right store, and the stored-location check only\n * proves the store kept the key it was handed. So the key is not merely checked\n * for shape, it is recomputed: it has to be exactly what this release prefix and\n * this source path produce, or a release could overwrite a *different* release.\n */\nconst validateObjectKey = (\n releasePrefix: string,\n file: LinkedAppReleaseFile,\n): void => {\n const sourcePath = normalizeReleasePath(\n String(file.sourcePath ?? ''),\n 'source path',\n );\n const objectKey = normalizeReleasePath(\n String(file.objectKey ?? ''),\n 'object key',\n );\n const expected = releaseObjectKey(releasePrefix, sourcePath);\n if (objectKey !== expected) {\n throw new Error(\n `Release manifest object key is not under the release prefix: ` +\n `\"${file.objectKey}\" (expected \"${expected}\"). Rebuild the release; ` +\n 'a manifest may only upload to its own prefix.',\n );\n }\n};\n\nexport const loadReleaseManifest = (\n appRoot: string,\n manifestPath = MANIFEST_SOURCE_PATH,\n): LoadedReleaseManifest => {\n const absolutePath = resolveExistingPathWithinRoot(appRoot, manifestPath);\n const manifest = JSON.parse(\n fs.readFileSync(absolutePath, 'utf8'),\n ) as LinkedAppReleaseManifest;\n\n if (manifest.schemaVersion !== 1) {\n throw new Error(\n `Unsupported release manifest schema: ${manifest.schemaVersion}`,\n );\n }\n if (manifest.target !== 'web' || manifest.publishable !== true) {\n throw new Error('Only publishable web release manifests may be uploaded');\n }\n if (!Array.isArray(manifest.files) || manifest.files.length === 0) {\n throw new Error('Release manifest contains no files');\n }\n if (!manifest.destination?.releasePrefix) {\n throw new Error('Release manifest has no release prefix');\n }\n const releasePrefix = normalizeReleasePath(\n manifest.destination.releasePrefix,\n 'release prefix',\n );\n for (const file of manifest.files) {\n validateObjectKey(releasePrefix, file);\n }\n\n return {absolutePath, manifest};\n};\n\n/**\n * The manifest records the `accessURL` of the store it was built for. If the\n * configured store now writes somewhere else, the release is not the one that\n * was built and publishing stops. Trailing slashes are not significant.\n */\nconst validateDestination = (\n manifest: LinkedAppReleaseManifest,\n store: IFileStore,\n) => {\n const expected = normalizeAccessURL(manifest.destination.accessURL);\n const actual = normalizeAccessURL(store.accessURL);\n if (expected !== actual) {\n throw new Error(\n `Release destination does not match the manifest (manifest was built for ${\n expected || '(empty)'\n }, the configured appAssets store writes to ${actual || '(empty)'})`,\n );\n }\n};\n\nconst hashBuffer = (content: Buffer): string =>\n crypto.createHash('sha256').update(content).digest('hex');\n\n/**\n * Re-hash the file on disk before uploading. This needs no support from the\n * store and is what actually guarantees the bytes match the manifest.\n */\nconst validateLocalFile = (\n appRoot: string,\n file: LinkedAppReleaseFile,\n): string => {\n // `resolveExistingPathWithinRoot` resolves symlinks, so a source path that\n // points out of the app root through one is refused here too.\n const absolutePath = resolveExistingPathWithinRoot(appRoot, file.sourcePath);\n const content = fs.readFileSync(absolutePath);\n if (content.byteLength !== file.size || hashBuffer(content) !== file.sha256) {\n throw new Error(`Release artifact changed after build: ${file.sourcePath}`);\n }\n return absolutePath;\n};\n\nexport const planReleasePublish = (\n options: PlanReleasePublishOptions,\n): PublishPlan => {\n const {absolutePath, manifest} = loadReleaseManifest(\n options.appRoot,\n options.manifestPath,\n );\n validateDestination(manifest, options.store);\n\n for (const file of manifest.files) {\n validateLocalFile(options.appRoot, file);\n }\n\n return {\n releaseId: manifest.releaseId,\n manifestPath: absolutePath,\n manifestObjectKey: releaseObjectKey(\n manifest.destination.releasePrefix,\n MANIFEST_SOURCE_PATH,\n ),\n destination: manifest.destination,\n files: manifest.files,\n totalBytes: manifest.files.reduce((total, file) => total + file.size, 0),\n };\n};\n\n/**\n * Verify one uploaded object against the hash in the manifest.\n *\n * `statFile` is optional on `IFileStore`, and a store that has it may still\n * report no `sha256` (S3 only returns one when the object carries a checksum).\n * Neither case is a failure: verification is skipped, the key is reported back\n * as unverified, and the caller warns once. An `etag` is deliberately not used\n * as a substitute — it is not a content hash.\n */\nconst verifyUpload = async (\n store: IFileStore,\n objectKey: string,\n expected: {size: number; sha256: string},\n): Promise<'verified' | 'unsupported' | 'no-hash'> => {\n if (typeof store.statFile !== 'function') return 'unsupported';\n\n const stat = await store.statFile(objectKey);\n if (!stat) {\n throw new Error(`Uploaded artifact is missing from the store: ${objectKey}`);\n }\n if (stat.size !== expected.size) {\n throw new Error(\n `Uploaded artifact size does not match the manifest: ${objectKey}`,\n );\n }\n if (!stat.sha256) return 'no-hash';\n if (stat.sha256 !== expected.sha256) {\n throw new Error(`Uploaded artifact verification failed: ${objectKey}`);\n }\n return 'verified';\n};\n\nexport const publishRelease = async (\n options: PublishReleaseOptions,\n): Promise<PublishResult> => {\n const plan = planReleasePublish(options);\n\n if (!options.yes) {\n return {\n releaseId: plan.releaseId,\n uploadedFiles: 0,\n uploadedBytes: 0,\n dryRun: true,\n unverified: [],\n };\n }\n\n const unverified: string[] = [];\n let warnedAboutVerification = false;\n const noteUnverified = (objectKey: string, reason: string) => {\n unverified.push(objectKey);\n if (warnedAboutVerification) return;\n warnedAboutVerification = true;\n options.onWarning?.(\n `Cannot verify uploads against a store hash (${reason}). Files are still ` +\n 'checked against the manifest before upload; the remote copy is not re-checked.',\n );\n };\n\n const upload = async (\n objectKey: string,\n content: Buffer,\n contentType: string,\n cacheControl: string,\n sha256: string,\n ) => {\n // `preventDuplicates: false` is explicit: a release key must be exactly the\n // key in the manifest. `LocalFileStore` otherwise appends a random suffix,\n // which would both break the URL and make verification meaningless.\n const storedURL = await options.store.saveFile(objectKey, content, {\n mimeType: contentType,\n cacheControl,\n preventDuplicates: false,\n });\n // A release key has to survive the round trip verbatim, or the published\n // URLs in the bundle point at nothing. Some stores sanitise or suffix the\n // path they are given; say so plainly instead of failing later with a\n // confusing \"missing from the store\".\n if (typeof storedURL === 'string' && !storedURL.endsWith(objectKey)) {\n throw new Error(\n `The file store did not store the release object under its own key. ` +\n `Expected a location ending in \"${objectKey}\", got \"${storedURL}\". ` +\n 'A release store must keep object keys verbatim.',\n );\n }\n const outcome = await verifyUpload(options.store, objectKey, {\n size: content.byteLength,\n sha256,\n });\n if (outcome === 'unsupported') {\n noteUnverified(objectKey, 'this store does not implement statFile');\n } else if (outcome === 'no-hash') {\n noteUnverified(objectKey, 'the store reports no sha256 for stored objects');\n }\n };\n\n const totalUploads = plan.files.length + 1;\n let completedUploads = 0;\n\n /**\n * A failure halfway through leaves a partial prefix behind, so the message\n * has to say which object failed, where it was going and how much is already\n * there — and that a re-run finishes the job, since keys are deterministic\n * and every object is overwritten with identical bytes.\n */\n const describeFailure = (\n error: unknown,\n what: string,\n objectKey: string,\n ): Error => {\n const cause = error instanceof Error ? error : new Error(String(error));\n const failure = new Error(\n `Release upload failed while uploading ${what} to \"${objectKey}\" ` +\n `(store ${options.store.accessURL || '(no accessURL)'}): ${cause.message}. ` +\n `${completedUploads} of ${totalUploads} objects were already uploaded under ` +\n `\"${plan.destination.releasePrefix}\"; the release manifest was not uploaded, so the ` +\n 'release is incomplete. Re-running publish-app resumes it — object keys are ' +\n 'deterministic and already-uploaded objects are rewritten with identical bytes.',\n );\n (failure as Error & {cause?: unknown}).cause = cause;\n failure.stack = cause.stack\n ? `${failure.message}\\nCaused by: ${cause.stack}`\n : failure.stack;\n return failure;\n };\n\n for (const file of plan.files) {\n const absolutePath = resolveExistingPathWithinRoot(\n options.appRoot,\n file.sourcePath,\n );\n try {\n await upload(\n file.objectKey,\n fs.readFileSync(absolutePath),\n file.contentType,\n file.cacheControl,\n file.sha256,\n );\n } catch (error) {\n throw describeFailure(error, file.sourcePath, file.objectKey);\n }\n completedUploads += 1;\n options.onProgress?.({\n completed: completedUploads,\n total: totalUploads,\n objectKey: file.objectKey,\n });\n }\n\n // The manifest goes last: its presence under the release prefix is what marks\n // the release as complete.\n const manifestBody = fs.readFileSync(plan.manifestPath);\n try {\n await upload(\n plan.manifestObjectKey,\n manifestBody,\n MANIFEST_CONTENT_TYPE,\n ENTRY_CACHE_CONTROL,\n hashBuffer(manifestBody),\n );\n } catch (error) {\n throw describeFailure(error, 'the release manifest', plan.manifestObjectKey);\n }\n completedUploads += 1;\n options.onProgress?.({\n completed: completedUploads,\n total: totalUploads,\n objectKey: plan.manifestObjectKey,\n });\n\n return {\n releaseId: plan.releaseId,\n uploadedFiles: totalUploads,\n uploadedBytes: plan.totalBytes + manifestBody.byteLength,\n dryRun: false,\n unverified,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../../src/app-release/publisher.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from 'crypto';\nimport fs from 'fs';\nimport type {IFileStore} from '@_linked/core/interfaces/IFileStore';\nimport {normalizeAccessURL} from './app-assets-store.js';\nimport {\n MANIFEST_CONTENT_TYPE,\n MANIFEST_SOURCE_PATH,\n ENTRY_CACHE_CONTROL,\n releaseObjectKey,\n} from './create-release-manifest.js';\nimport {normalizeReleasePath, resolveExistingPathWithinRoot} from './paths.js';\nimport type {\n LinkedAppReleaseFile,\n LinkedAppReleaseManifest,\n PublishPlan,\n PublishResult,\n} from './types.js';\n\nexport interface PlanReleasePublishOptions {\n appRoot: string;\n manifestPath?: string;\n store: IFileStore;\n}\n\nexport interface LoadedReleaseManifest {\n absolutePath: string;\n manifest: LinkedAppReleaseManifest;\n}\n\nexport interface PublishReleaseOptions extends PlanReleasePublishOptions {\n yes?: boolean;\n onProgress?: (progress: PublishProgress) => void;\n onWarning?: (message: string) => void;\n}\n\nexport interface PublishProgress {\n completed: number;\n total: number;\n objectKey: string;\n}\n\n/**\n * Every object of a release must land under that release's own prefix.\n *\n * The manifest is a plain file on disk: a hand-edited or foreign one can name\n * any `objectKey` it likes, and nothing else catches it — the `accessURL` check\n * only proves the store is the right store, and the stored-location check only\n * proves the store kept the key it was handed. So the key is not merely checked\n * for shape, it is recomputed: it has to be exactly what this release prefix and\n * this source path produce, or a release could overwrite a *different* release.\n */\nconst validateObjectKey = (\n releasePrefix: string,\n file: LinkedAppReleaseFile,\n): void => {\n const sourcePath = normalizeReleasePath(\n String(file.sourcePath ?? ''),\n 'source path',\n );\n const objectKey = normalizeReleasePath(\n String(file.objectKey ?? ''),\n 'object key',\n );\n const expected = releaseObjectKey(releasePrefix, sourcePath);\n if (objectKey !== expected) {\n throw new Error(\n `Release manifest object key is not under the release prefix: ` +\n `\"${file.objectKey}\" (expected \"${expected}\"). Rebuild the release; ` +\n 'a manifest may only upload to its own prefix.',\n );\n }\n};\n\nexport const loadReleaseManifest = (\n appRoot: string,\n manifestPath = MANIFEST_SOURCE_PATH,\n): LoadedReleaseManifest => {\n const absolutePath = resolveExistingPathWithinRoot(appRoot, manifestPath);\n const manifest = JSON.parse(\n fs.readFileSync(absolutePath, 'utf8'),\n ) as LinkedAppReleaseManifest;\n\n if (manifest.schemaVersion !== 1) {\n throw new Error(\n `Unsupported release manifest schema: ${manifest.schemaVersion}`,\n );\n }\n if (manifest.target !== 'web' || manifest.publishable !== true) {\n throw new Error('Only publishable web release manifests may be uploaded');\n }\n if (!Array.isArray(manifest.files) || manifest.files.length === 0) {\n throw new Error('Release manifest contains no files');\n }\n if (!manifest.destination?.releasePrefix) {\n throw new Error('Release manifest has no release prefix');\n }\n const releasePrefix = normalizeReleasePath(\n manifest.destination.releasePrefix,\n 'release prefix',\n );\n for (const file of manifest.files) {\n validateObjectKey(releasePrefix, file);\n }\n\n return {absolutePath, manifest};\n};\n\n/**\n * The manifest records the `accessURL` of the store it was built for. If the\n * configured store now writes somewhere else, the release is not the one that\n * was built and publishing stops. Trailing slashes are not significant.\n */\nconst validateDestination = (\n manifest: LinkedAppReleaseManifest,\n store: IFileStore,\n) => {\n const expected = normalizeAccessURL(manifest.destination.accessURL);\n const actual = normalizeAccessURL(store.accessURL);\n if (expected !== actual) {\n throw new Error(\n `Release destination does not match the manifest (manifest was built for ${\n expected || '(empty)'\n }, the configured appAssets store writes to ${actual || '(empty)'})`,\n );\n }\n};\n\nconst hashBuffer = (content: Buffer): string =>\n crypto.createHash('sha256').update(content).digest('hex');\n\n/**\n * Re-hash the file on disk before uploading. This needs no support from the\n * store and is what actually guarantees the bytes match the manifest.\n */\nconst validateLocalFile = (\n appRoot: string,\n file: LinkedAppReleaseFile,\n): string => {\n // `resolveExistingPathWithinRoot` resolves symlinks, so a source path that\n // points out of the app root through one is refused here too.\n const absolutePath = resolveExistingPathWithinRoot(appRoot, file.sourcePath);\n const content = fs.readFileSync(absolutePath);\n if (content.byteLength !== file.size || hashBuffer(content) !== file.sha256) {\n throw new Error(`Release artifact changed after build: ${file.sourcePath}`);\n }\n return absolutePath;\n};\n\nexport const planReleasePublish = (\n options: PlanReleasePublishOptions,\n): PublishPlan => {\n const {absolutePath, manifest} = loadReleaseManifest(\n options.appRoot,\n options.manifestPath,\n );\n validateDestination(manifest, options.store);\n\n for (const file of manifest.files) {\n validateLocalFile(options.appRoot, file);\n }\n\n return {\n releaseId: manifest.releaseId,\n manifestPath: absolutePath,\n manifestObjectKey: releaseObjectKey(\n manifest.destination.releasePrefix,\n MANIFEST_SOURCE_PATH,\n ),\n destination: manifest.destination,\n files: manifest.files,\n totalBytes: manifest.files.reduce((total, file) => total + file.size, 0),\n };\n};\n\n/**\n * Verify one uploaded object against the hash in the manifest.\n *\n * `statFile` is optional on `IFileStore`, and a store that has it may still\n * report no `sha256` (S3 only returns one when the object carries a checksum).\n * Neither case is a failure: verification is skipped, the key is reported back\n * as unverified, and the caller warns once. An `etag` is deliberately not used\n * as a substitute — it is not a content hash.\n */\nconst verifyUpload = async (\n store: IFileStore,\n objectKey: string,\n expected: {size: number; sha256: string},\n): Promise<'verified' | 'unsupported' | 'no-hash'> => {\n if (typeof store.statFile !== 'function') return 'unsupported';\n\n const stat = await store.statFile(objectKey);\n if (!stat) {\n throw new Error(`Uploaded artifact is missing from the store: ${objectKey}`);\n }\n if (stat.size !== expected.size) {\n throw new Error(\n `Uploaded artifact size does not match the manifest: ${objectKey}`,\n );\n }\n if (!stat.sha256) return 'no-hash';\n if (stat.sha256 !== expected.sha256) {\n throw new Error(`Uploaded artifact verification failed: ${objectKey}`);\n }\n return 'verified';\n};\n\nexport const publishRelease = async (\n options: PublishReleaseOptions,\n): Promise<PublishResult> => {\n const plan = planReleasePublish(options);\n\n if (!options.yes) {\n return {\n releaseId: plan.releaseId,\n uploadedFiles: 0,\n uploadedBytes: 0,\n dryRun: true,\n unverified: [],\n };\n }\n\n const unverified: string[] = [];\n let warnedAboutVerification = false;\n const noteUnverified = (objectKey: string, reason: string) => {\n unverified.push(objectKey);\n if (warnedAboutVerification) return;\n warnedAboutVerification = true;\n options.onWarning?.(\n `Cannot verify uploads against a store hash (${reason}). Files are still ` +\n 'checked against the manifest before upload; the remote copy is not re-checked.',\n );\n };\n\n const upload = async (\n objectKey: string,\n content: Buffer,\n contentType: string,\n cacheControl: string,\n sha256: string,\n ) => {\n // A release key must be exactly the key in the manifest. Disable duplicate\n // renaming and ask the store to preserve the validated relative path; any\n // suffix or sanitisation would break the URL and make verification useless.\n const storedURL = await options.store.saveFile(objectKey, content, {\n mimeType: contentType,\n cacheControl,\n preventDuplicates: false,\n preservePath: true,\n });\n // A release key has to survive the round trip verbatim, or the published\n // URLs in the bundle point at nothing. Some stores sanitise or suffix the\n // path they are given; say so plainly instead of failing later with a\n // confusing \"missing from the store\".\n if (typeof storedURL === 'string' && !storedURL.endsWith(objectKey)) {\n throw new Error(\n `The file store did not store the release object under its own key. ` +\n `Expected a location ending in \"${objectKey}\", got \"${storedURL}\". ` +\n 'A release store must keep object keys verbatim.',\n );\n }\n const outcome = await verifyUpload(options.store, objectKey, {\n size: content.byteLength,\n sha256,\n });\n if (outcome === 'unsupported') {\n noteUnverified(objectKey, 'this store does not implement statFile');\n } else if (outcome === 'no-hash') {\n noteUnverified(objectKey, 'the store reports no sha256 for stored objects');\n }\n };\n\n const totalUploads = plan.files.length + 1;\n let completedUploads = 0;\n\n /**\n * A failure halfway through leaves a partial prefix behind, so the message\n * has to say which object failed, where it was going and how much is already\n * there — and that a re-run finishes the job, since keys are deterministic\n * and every object is overwritten with identical bytes.\n */\n const describeFailure = (\n error: unknown,\n what: string,\n objectKey: string,\n ): Error => {\n const cause = error instanceof Error ? error : new Error(String(error));\n const failure = new Error(\n `Release upload failed while uploading ${what} to \"${objectKey}\" ` +\n `(store ${options.store.accessURL || '(no accessURL)'}): ${cause.message}. ` +\n `${completedUploads} of ${totalUploads} objects were already uploaded under ` +\n `\"${plan.destination.releasePrefix}\"; the release manifest was not uploaded, so the ` +\n 'release is incomplete. Re-running publish-app resumes it — object keys are ' +\n 'deterministic and already-uploaded objects are rewritten with identical bytes.',\n );\n (failure as Error & {cause?: unknown}).cause = cause;\n failure.stack = cause.stack\n ? `${failure.message}\\nCaused by: ${cause.stack}`\n : failure.stack;\n return failure;\n };\n\n for (const file of plan.files) {\n const absolutePath = resolveExistingPathWithinRoot(\n options.appRoot,\n file.sourcePath,\n );\n try {\n await upload(\n file.objectKey,\n fs.readFileSync(absolutePath),\n file.contentType,\n file.cacheControl,\n file.sha256,\n );\n } catch (error) {\n throw describeFailure(error, file.sourcePath, file.objectKey);\n }\n completedUploads += 1;\n options.onProgress?.({\n completed: completedUploads,\n total: totalUploads,\n objectKey: file.objectKey,\n });\n }\n\n // The manifest goes last: its presence under the release prefix is what marks\n // the release as complete.\n const manifestBody = fs.readFileSync(plan.manifestPath);\n try {\n await upload(\n plan.manifestObjectKey,\n manifestBody,\n MANIFEST_CONTENT_TYPE,\n ENTRY_CACHE_CONTROL,\n hashBuffer(manifestBody),\n );\n } catch (error) {\n throw describeFailure(error, 'the release manifest', plan.manifestObjectKey);\n }\n completedUploads += 1;\n options.onProgress?.({\n completed: completedUploads,\n total: totalUploads,\n objectKey: plan.manifestObjectKey,\n });\n\n return {\n releaseId: plan.releaseId,\n uploadedFiles: totalUploads,\n uploadedBytes: plan.totalBytes + manifestBody.byteLength,\n dryRun: false,\n unverified,\n };\n};\n"]}
|
package/lib/esm/launch.js
CHANGED
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
// ships legacy-signature property decorators and tsx/esbuild's default
|
|
9
9
|
// otherwise emits TC39 standard decorators, breaking property
|
|
10
10
|
// registration in user scripts.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
//
|
|
12
|
+
// The hooks run on their own thread, which never sees the app's `.env`: the CLI
|
|
13
|
+
// loads it later. So the CSS loader is told its naming mode here, resolved
|
|
14
|
+
// before anything loads — see loader-mode.ts.
|
|
15
|
+
import { registerLoaders } from './loaders/register.js';
|
|
16
|
+
registerLoaders();
|
|
14
17
|
import('./cli.js').catch((err) => {
|
|
15
18
|
console.error(err);
|
|
16
19
|
process.exit(1);
|
package/lib/esm/launch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launch.js","sourceRoot":"","sources":["../../src/launch.ts"],"names":[],"mappings":";AACA,uEAAuE;AACvE,yEAAyE;AACzE,+DAA+D;AAC/D,EAAE;AACF,0EAA0E;AAC1E,wEAAwE;AACxE,uEAAuE;AACvE,8DAA8D;AAC9D,gCAAgC;AAChC,
|
|
1
|
+
{"version":3,"file":"launch.js","sourceRoot":"","sources":["../../src/launch.ts"],"names":[],"mappings":";AACA,uEAAuE;AACvE,yEAAyE;AACzE,+DAA+D;AAC/D,EAAE;AACF,0EAA0E;AAC1E,wEAAwE;AACxE,uEAAuE;AACvE,8DAA8D;AAC9D,gCAAgC;AAChC,EAAE;AACF,gFAAgF;AAChF,2EAA2E;AAC3E,8CAA8C;AAC9C,OAAO,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAEtD,eAAe,EAAE,CAAC;AAElB,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC/B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\n// Bootstrap entry for the `linked` bin. Registers Node module hooks at\n// the top level, then dynamically imports the CLI so any TS/CSS that the\n// CLI later loads from a user's app flows through these hooks.\n//\n// We use a custom ts-loader (based on esbuild) instead of `tsx` so we can\n// force `experimentalDecorators: true` on the transform — @_linked/core\n// ships legacy-signature property decorators and tsx/esbuild's default\n// otherwise emits TC39 standard decorators, breaking property\n// registration in user scripts.\n//\n// The hooks run on their own thread, which never sees the app's `.env`: the CLI\n// loads it later. So the CSS loader is told its naming mode here, resolved\n// before anything loads — see loader-mode.ts.\nimport {registerLoaders} from './loaders/register.js';\n\nregisterLoaders();\n\nimport('./cli.js').catch((err) => {\n console.error(err);\n process.exit(1);\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,uBAAuB,GAClC,mBAAmB,MAAM,EAAE,KAC1B,OAAO,CAAC,IAAI,CA+Bd,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS;IAC7C,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB,KAAG,MAAM,EAeT,CAAC;AAyCF;;;;;GAKG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,GAAG,CAAC,CAyB7D;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,+BAA+B;IAC/B,MAAM,EAAE,WAAW,GAAG,oBAAoB,CAAC;IAC3C,yDAAyD;IACzD,eAAe,EAAE,OAAO,CAAC;IACzB,2EAA2E;IAC3E,KAAK,EAAE,OAAO,CAAC;IACf,0EAA0E;IAC1E,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AAEnD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,SAAgB,GACvB,cAAc,EAAE,CAIlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,SAAgB,EACxB,OAAO,GAAE;IAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAM,GAC3E,YAAY,EAAE,CA4BhB;AAgJD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAMnE;AAED,mEAAmE;AACnE,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,QAAQ,SAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAkD5E"}
|
package/lib/esm/lifecycle.js
CHANGED
|
@@ -21,6 +21,8 @@ import { getPackageJSON } from './utils.js';
|
|
|
21
21
|
import { isLinkedPackageJson } from './installed-packages.js';
|
|
22
22
|
import { readManifest } from './localize/manifest.js';
|
|
23
23
|
import { parseWorkspacePatterns, isWorkspacePathNegated } from './workspace-globs.js';
|
|
24
|
+
// Shared with the CSS loader's mode resolution, which must pick the same profiles.
|
|
25
|
+
import { readEnvNamesFromArgv } from './loader-mode.js';
|
|
24
26
|
/**
|
|
25
27
|
* Load the app's environment into `process.env`, then re-apply the original
|
|
26
28
|
* shell env so it always wins on conflict. Idempotent — runs at most once.
|
|
@@ -132,13 +134,6 @@ const loadEnvCmdrc = (envCmdrcPath, environmentNames) => __awaiter(void 0, void
|
|
|
132
134
|
console.log('No environment specified, using development');
|
|
133
135
|
}
|
|
134
136
|
});
|
|
135
|
-
const readEnvNamesFromArgv = () => {
|
|
136
|
-
const args = process.argv.slice(2);
|
|
137
|
-
const envIndex = args.indexOf('--env');
|
|
138
|
-
if (envIndex === -1)
|
|
139
|
-
return [];
|
|
140
|
-
return (args[envIndex + 1] || '').split(',').filter(Boolean);
|
|
141
|
-
};
|
|
142
137
|
/**
|
|
143
138
|
* Discover and load the app's storage-config bootstrap file. Tries the
|
|
144
139
|
* canonical `linked.backend.storage.{ts,js}` first, then legacy paths.
|
package/lib/esm/lifecycle.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["// Lifecycle helpers shared by the Vite-based dev orchestrator.\n//\n// Extracted from cli-methods.ts so the SSR module graph (started from\n// `commands/start.ts`) doesn't have to walk the rest of that file. The\n// the older helpers in cli-methods.ts contain many dynamic\n// `import(<variable>)` calls Vite can't analyze statically and would\n// emit warnings about — even though startWithVite never calls them.\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport chalk from 'chalk';\nimport {getPackageJSON} from './utils.js';\nimport {isLinkedPackageJson} from './installed-packages.js';\nimport {readManifest} from './localize/manifest.js';\nimport {parseWorkspacePatterns, isWorkspacePathNegated} from './workspace-globs.js';\nimport type {PackageDetails} from './interfaces.js';\n\n/**\n * Load the app's environment into `process.env`, then re-apply the original\n * shell env so it always wins on conflict. Idempotent — runs at most once.\n *\n * Two sources, tried in this order:\n * 1. `.env` (Node-native `process.loadEnvFile`, no dependency) — a flat file.\n * This is what the app template ships and the only form that will survive.\n * `--env` is not consulted here: a flat `.env` has no profiles, so\n * NODE_ENV comes from the file or the shell.\n * 2. `.env-cmdrc.json` (DEPRECATED, via `env-cmd`) — profile-based; honours\n * `--env a,b` and merges `_main` + the named profiles. Still read when it\n * is the only file present, so no existing app breaks, but it warns.\n *\n * `.env` going first is what makes migrating a one-step job: add the flat file\n * and it takes over. The profile file can then be deleted whenever convenient.\n *\n * If neither file exists we skip silently — CN-hosted apps have their env\n * injected into the child process at spawn time, so there's nothing to read\n * from disk.\n */\nexport const ensureEnvironmentLoaded = async (\n environmentNames?: string[],\n): Promise<void> => {\n if (process.env.ENV_VARS_LOADED) return;\n const cwd = process.cwd();\n const envCmdrcPath = path.join(cwd, '.env-cmdrc.json');\n const dotEnvPath = path.join(cwd, '.env');\n\n // Snapshot the original shell env — it should always take priority over\n // whatever a file sets (so injected/production env wins over dev defaults).\n const shellEnv = {...process.env};\n\n const hasDotEnv = fs.existsSync(dotEnvPath);\n const hasEnvCmdrc = fs.existsSync(envCmdrcPath);\n\n for (const notice of envDeprecationNotices({hasEnvCmdrc, hasDotEnv})) {\n console.warn(chalk.yellow(notice));\n }\n\n if (hasDotEnv) {\n // Native flat-file loader (Node 20.12+). Populates process.env from `.env`.\n process.loadEnvFile(dotEnvPath);\n } else if (hasEnvCmdrc) {\n await loadEnvCmdrc(envCmdrcPath, environmentNames);\n } else {\n console.warn(\n 'No .env or .env-cmdrc.json found in this folder — relying on the ambient environment.',\n );\n }\n\n // Re-apply shell env so it always wins over file values.\n process.env = {...process.env, ...shellEnv};\n process.env.ENV_VARS_LOADED = 'true';\n};\n\n/**\n * What to tell an app about where its environment came from.\n *\n * `.env-cmdrc.json` is still read when it is the only file present, so no app\n * breaks today. But it is the only reason `--env` exists, and both are going\n * away.\n *\n * The case worth shouting about is an app holding both files: `.env` wins, so\n * the profile file and every `--env` name passed with it do nothing. That is\n * the intended migration path, but it is invisible from the outside — values\n * an app still believes it is getting from a profile are simply absent.\n *\n * Pure and exported so the messages can be asserted without a chdir.\n */\nexport const envDeprecationNotices = (sources: {\n hasEnvCmdrc: boolean;\n hasDotEnv: boolean;\n}): string[] => {\n if (!sources.hasEnvCmdrc) return [];\n const notices = [\n '.env-cmdrc.json is deprecated and will be removed in a future major release.',\n ' Move its values into a flat `.env`, and supply anything that differs per ' +\n 'deployment from the environment itself. `--env` goes away with it.',\n ];\n if (sources.hasDotEnv) {\n notices.push(\n ' This app has BOTH files. `.env` wins, so `.env-cmdrc.json` — and any ' +\n '`--env` profile named with it — is being ignored entirely. Delete it once ' +\n 'the flat file is complete.',\n );\n }\n return notices;\n};\n\n/**\n * Legacy loader: reads `.env-cmdrc.json`, merges `_main` plus the profile(s)\n * named by `--env a,b` (default `development`). Kept for CN and existing apps\n * until they migrate to a flat `.env`.\n */\nconst loadEnvCmdrc = async (\n envCmdrcPath: string,\n environmentNames?: string[],\n): Promise<void> => {\n // env-cmd ships ESM; literal specifier is fine for Vite's analyzer.\n const {GetEnvVars} = await import('env-cmd');\n const vars = await GetEnvVars({envFile: {filePath: envCmdrcPath}});\n const environments = Object.keys(vars);\n\n if (environments.includes('_main')) {\n process.env = {...process.env, ...vars._main};\n }\n // Callers that parsed `--env` themselves pass the names in. Commands that\n // have not been converted yet still have their names scraped off argv.\n const requested = environmentNames?.length\n ? environmentNames\n : readEnvNamesFromArgv();\n if (requested.length) {\n requested.forEach((name) => {\n if (environments.includes(name)) {\n console.log('Environment: ' + name);\n process.env = {...process.env, ...vars[name]};\n } else {\n console.warn(\n `Environment ${name} not found in .env-cmdrc.json. Available: ${environments.join(', ')}`,\n );\n }\n });\n } else {\n process.env = {...process.env, ...vars.development};\n console.log('No environment specified, using development');\n }\n};\n\nconst readEnvNamesFromArgv = (): string[] => {\n const args = process.argv.slice(2);\n const envIndex = args.indexOf('--env');\n if (envIndex === -1) return [];\n return (args[envIndex + 1] || '').split(',').filter(Boolean);\n};\n\n/**\n * Discover and load the app's storage-config bootstrap file. Tries the\n * canonical `linked.backend.storage.{ts,js}` first, then legacy paths.\n * Returns whatever the file's default export evaluates to, or undefined\n * if no candidate exists.\n */\nexport async function loadBackendStorageConfig(): Promise<any> {\n const cwd = process.cwd();\n const candidates = [\n path.join(cwd, 'linked.backend.storage.ts'),\n path.join(cwd, 'linked.backend.storage.js'),\n path.join(cwd, 'backend-storage-config.ts'),\n path.join(cwd, 'backend-storage-config.js'),\n path.join(cwd, 'scripts', 'backend-storage-config.js'),\n path.join(cwd, 'scripts', 'backend-storage-config.ts'),\n path.join(cwd, 'scripts', 'storage-config.js'),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n // Variable specifier is intentional — we discover the path at\n // runtime by probing the candidate list, so static analysis is\n // impossible.\n return import(/* @vite-ignore */ candidate);\n }\n }\n console.warn(\n chalk.yellow(\n '[linked.backend.storage] no linked.backend.storage.{ts,js} found at app root.',\n ),\n );\n return undefined;\n}\n\n/**\n * A local package directory found by {@link discoverLocalPackages}, together\n * with the facts that decide what can be done with it.\n *\n * The facts are recorded rather than filtered on, because the bug this type\n * exists to fix was a SILENT filter: `build-all` discovered only packages\n * carrying `linkedPackage: true` and printed nothing about the rest, so\n * `@_linked/maps` — a shipped dependency that simply never got the flag — was\n * dropped from a green build for as long as nobody counted the names.\n */\nexport interface LocalPackage extends PackageDetails {\n /** Where the walk found it. */\n source: 'workspace' | 'local-packages-dir';\n /** `linkedPackage: true` — see `isLinkedPackageJson`. */\n isLinkedPackage: boolean;\n /** `linkedApp: true` — built by `linked build-app`, not `linked build`. */\n isApp: boolean;\n /** Has a `build` script of its own, which is what `build-all` invokes. */\n hasBuildScript: boolean;\n}\n\n/**\n * Directory holding localized checkouts (`linked localize`). It is\n * deliberately in NO workspace glob — that is the whole point of the design,\n * since npm learning about these checkouts is what made their predecessor\n * under `packages/` a trap — so any walk of `workspaces` alone cannot see it\n * and has to be told about it separately.\n */\nexport const LOCAL_PACKAGES_DIR = 'packages-local';\n\n/**\n * Walk the app's `package.json` `workspaces` field and return every\n * workspace package that declares `\"linkedPackage\": true`.\n *\n * Lives here (not in cli-methods.ts) so consumers like LinkedServer can\n * import it without dragging the rest of the legacy cli-methods flow into\n * Vite's SSR module graph.\n *\n * Kept deliberately narrow: this is the set the dev resolver and the runtime\n * treat as linked packages. Commands that want every *buildable* local\n * package — flag or no flag, workspace or localized checkout — want\n * {@link discoverLocalPackages} instead.\n */\nexport function getLincdPackages(\n rootPath = process.cwd(),\n): PackageDetails[] {\n return discoverLocalPackages(rootPath, {includeLocalPackagesDir: false})\n .filter((pkg) => pkg.isLinkedPackage)\n .map(({path: packagePath, packageName}) => ({path: packagePath, packageName}));\n}\n\n/**\n * Every local package directory this app can see, whether or not it declares\n * `linkedPackage: true`.\n *\n * Two sources, because the workspace globs are not the whole picture any more:\n *\n * 1. the `workspaces` field (negations honoured — see ./workspace-globs.js);\n * 2. `packages-local/`, the localized checkouts, which is in no glob.\n *\n * Nothing is filtered out here. Callers decide what they can act on and are\n * expected to SAY what they skipped and why.\n */\nexport function discoverLocalPackages(\n rootPath = process.cwd(),\n options: {includeLocalPackagesDir?: boolean; localPackagesDir?: string} = {},\n): LocalPackage[] {\n const {includeLocalPackagesDir = true, localPackagesDir = LOCAL_PACKAGES_DIR} =\n options;\n\n let pack = getPackageJSON(rootPath);\n if (!pack || !pack.workspaces) {\n const originalRoot = rootPath;\n for (let i = 0; i <= 3; i++) {\n rootPath = path.join(originalRoot, ...Array(i).fill('..'));\n pack = getPackageJSON(rootPath);\n if (pack && pack.workspaces) break;\n }\n if (!pack || !pack.workspaces) {\n // Standalone apps (scaffolded with `linked create-app`) don't have\n // workspaces — expected. Fall back to the original root so a\n // `packages-local/` beside it is still found.\n rootPath = originalRoot;\n }\n }\n\n const res: LocalPackage[] = [];\n if (pack && pack.workspaces) {\n checkWorkspaces(rootPath, pack.workspaces, res);\n }\n if (includeLocalPackagesDir) {\n checkLocalPackagesDir(rootPath, localPackagesDir, res);\n }\n return res;\n}\n\n/**\n * Add every immediate subdirectory of `packages-local/` that holds a\n * `package.json`. No glob, no negations: the directory has no `workspaces`\n * entry to interpret, its contents are there because a developer localized\n * them on purpose, and each one is a plain checkout.\n */\nfunction checkLocalPackagesDir(\n rootPath: string,\n localPackagesDir: string,\n res: LocalPackage[],\n) {\n const dir = path.join(rootPath, localPackagesDir);\n if (!fs.existsSync(dir)) return;\n const already = new Set(res.map((pkg) => path.resolve(pkg.path)));\n for (const entry of fs.readdirSync(dir)) {\n if (entry.startsWith('.')) continue;\n const packagePath = path.join(dir, entry);\n if (!fs.statSync(packagePath).isDirectory()) continue;\n // A checkout that some glob already picked up must not appear twice —\n // duplicates would be built twice and counted twice.\n if (already.has(path.resolve(packagePath))) continue;\n addPackage(packagePath, 'local-packages-dir', res);\n }\n}\n\nfunction checkWorkspaces(rootPath: string, workspaces: any, res: LocalPackage[]) {\n // Negated entries (\"!packages/core\") are excluded the way npm excludes them\n // — including from the exact-path branch below, which npm also subjects to\n // them. See ./workspace-globs.js.\n const {patterns, negatedPatterns} = parseWorkspacePatterns(workspaces);\n const checkUnlessNegated = (packagePath: string) => {\n const rel = path.relative(rootPath, packagePath).split(path.sep).join('/');\n if (isWorkspacePathNegated(rel, negatedPatterns)) return;\n checkPackagePath(rootPath, packagePath, res);\n };\n patterns.forEach((workspace: string) => {\n const workspacePath = path.join(rootPath, workspace.replace('/*', ''));\n if (workspace.indexOf('/*') !== -1) {\n if (fs.existsSync(workspacePath)) {\n const folders = fs.readdirSync(workspacePath);\n folders.forEach((folder: string) => {\n if (folder !== './' && folder !== '../') {\n checkUnlessNegated(path.join(workspacePath, folder));\n }\n });\n }\n } else {\n checkUnlessNegated(workspacePath);\n }\n });\n}\n\nfunction checkPackagePath(rootPath: string, packagePath: string, res: LocalPackage[]) {\n const packageJsonPath = path.join(packagePath, 'package.json');\n if (!fs.existsSync(packageJsonPath)) return;\n const pack = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n if (pack && pack.workspaces) {\n checkWorkspaces(packagePath, pack.workspaces, res);\n } else if (pack) {\n addPackage(packagePath, 'workspace', res, pack);\n }\n}\n\nfunction addPackage(\n packagePath: string,\n source: LocalPackage['source'],\n res: LocalPackage[],\n packageJson?: any,\n) {\n const pack = packageJson ?? getPackageJSON(packagePath);\n if (!pack || !pack.name) return;\n res.push({\n path: packagePath,\n packageName: pack.name,\n source,\n // The one definition, shared with `linked build-package`.\n isLinkedPackage: isLinkedPackageJson(pack),\n isApp: pack.linkedApp === true,\n hasBuildScript: !!pack.scripts?.build,\n });\n}\n\n/**\n * Filters packages to only include those in the dependency tree of the app root\n */\nfunction filterPackagesByDependencyTree(\n allPackages: Map<string, PackageDetails>,\n appRootPath: string,\n): Map<string, PackageDetails> {\n const appPackageJson = getPackageJSON(appRootPath);\n if (!appPackageJson) {\n return allPackages;\n }\n\n const relevantPackages = new Map<string, PackageDetails>();\n const packagesToCheck = new Set<string>();\n\n // Start with direct dependencies from app root, plus everything localized:\n // a package created locally is linked but cannot be declared until it is\n // published (an unpublished range fails `npm install`), and being localized\n // already says this app is developed against it.\n [\n ...Object.keys(appPackageJson.dependencies || {}),\n ...localizedPackageNames(appRootPath),\n ].forEach((dep) => {\n if (allPackages.has(dep)) {\n packagesToCheck.add(dep);\n }\n });\n\n // Recursively add dependencies\n const processedPackages = new Set<string>();\n\n while (packagesToCheck.size > 0) {\n const packageName = Array.from(packagesToCheck)[0];\n packagesToCheck.delete(packageName);\n\n if (processedPackages.has(packageName)) {\n continue;\n }\n\n processedPackages.add(packageName);\n const packageDetails = allPackages.get(packageName);\n\n if (packageDetails) {\n relevantPackages.set(packageName, packageDetails);\n\n // Get this package's dependencies\n const packageJson = getPackageJSON(packageDetails.path);\n if (packageJson && packageJson.dependencies) {\n Object.keys(packageJson.dependencies).forEach((dep) => {\n if (allPackages.has(dep) && !processedPackages.has(dep)) {\n packagesToCheck.add(dep);\n }\n });\n }\n }\n }\n\n return relevantPackages;\n}\n\n/**\n * The package names recorded in the app's `local-packages.json` — what\n * `linked localize` has linked — read with localize's own reader. Read\n * tolerantly: `linked localize` refuses a malformed file (and warns about a\n * malformed entry) loudly, so here a missing or unusable file is simply\n * \"nothing localized\", and a malformed entry is skipped without a word.\n */\nexport function localizedPackageNames(appRootPath: string): string[] {\n try {\n return Object.keys(readManifest(appRootPath, {warn: () => {}}).entries);\n } catch {\n return [];\n }\n}\n\n/** A package `build-all` found but will not build, and why not. */\nexport interface SkippedPackage {\n packageName: string;\n path: string;\n reason: string;\n}\n\n/** What `build-all` found, and what it decided to do with each package. */\nexport interface BuildAllPlan {\n build: Map<string, PackageDetails>;\n skipped: SkippedPackage[];\n}\n\n/**\n * Decide what `build-all` builds.\n *\n * Every discovered package lands in exactly one of `build` or `skipped`, and\n * `skipped` carries a reason — because the failure mode this replaces was not\n * a narrow scan, it was a SILENT one. `@_linked/maps` is a shipped Create Now\n * dependency that never got `linkedPackage: true`; `build-all` dropped it and\n * printed nothing, so a build covering half the workspace exited 0 and people\n * acted on it. A skip nobody can see is worse than a failure.\n *\n * What counts as buildable is a CAPABILITY, not a declaration: `build-all`\n * invokes each package's own `build` script, so anything with one can be\n * built whether or not it carries the flag. The flag is still reported when\n * it is missing, since the dev resolver and `linked build` do require it.\n */\nexport function planBuildAll(rootPath = './', appRoot?: string): BuildAllPlan {\n const build = new Map<string, PackageDetails>();\n const skipped: SkippedPackage[] = [];\n const buildable: LocalPackage[] = [];\n\n for (const pkg of discoverLocalPackages(rootPath)) {\n const detail = {path: pkg.path, packageName: pkg.packageName};\n // Packages reached through a `../` workspace glob live outside this\n // repository; building them was never in scope for `build-all`.\n if (pkg.path.indexOf('../') !== -1 || pkg.path.indexOf('..\\\\') !== -1) {\n skipped.push({...detail, reason: 'outside this repository'});\n } else if (pkg.isApp) {\n skipped.push({\n ...detail,\n reason: 'is a linked app — build it with `linked build-app`',\n });\n } else if (!pkg.hasBuildScript) {\n skipped.push({...detail, reason: 'has no `build` script'});\n } else {\n buildable.push(pkg);\n build.set(pkg.packageName, detail);\n }\n }\n\n // Narrow to what this app actually depends on, if we are inside one.\n if (appRoot) {\n const appPackageJson = getPackageJSON(appRoot);\n const isAppWithLinkedDeps =\n appPackageJson &&\n !isLinkedPackageJson(appPackageJson) &&\n [\n ...Object.keys(appPackageJson.dependencies || {}),\n ...localizedPackageNames(appRoot),\n ].some((dep) => build.has(dep));\n\n if (isAppWithLinkedDeps) {\n const inTree = filterPackagesByDependencyTree(build, appRoot);\n for (const pkg of buildable) {\n if (inTree.has(pkg.packageName)) continue;\n build.delete(pkg.packageName);\n skipped.push({\n path: pkg.path,\n packageName: pkg.packageName,\n reason: `not in ${appPackageJson.name || 'this app'}'s dependency tree`,\n });\n }\n }\n }\n\n return {build, skipped};\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["// Lifecycle helpers shared by the Vite-based dev orchestrator.\n//\n// Extracted from cli-methods.ts so the SSR module graph (started from\n// `commands/start.ts`) doesn't have to walk the rest of that file. The\n// the older helpers in cli-methods.ts contain many dynamic\n// `import(<variable>)` calls Vite can't analyze statically and would\n// emit warnings about — even though startWithVite never calls them.\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport chalk from 'chalk';\nimport {getPackageJSON} from './utils.js';\nimport {isLinkedPackageJson} from './installed-packages.js';\nimport {readManifest} from './localize/manifest.js';\nimport {parseWorkspacePatterns, isWorkspacePathNegated} from './workspace-globs.js';\n// Shared with the CSS loader's mode resolution, which must pick the same profiles.\nimport {readEnvNamesFromArgv} from './loader-mode.js';\nimport type {PackageDetails} from './interfaces.js';\n\n/**\n * Load the app's environment into `process.env`, then re-apply the original\n * shell env so it always wins on conflict. Idempotent — runs at most once.\n *\n * Two sources, tried in this order:\n * 1. `.env` (Node-native `process.loadEnvFile`, no dependency) — a flat file.\n * This is what the app template ships and the only form that will survive.\n * `--env` is not consulted here: a flat `.env` has no profiles, so\n * NODE_ENV comes from the file or the shell.\n * 2. `.env-cmdrc.json` (DEPRECATED, via `env-cmd`) — profile-based; honours\n * `--env a,b` and merges `_main` + the named profiles. Still read when it\n * is the only file present, so no existing app breaks, but it warns.\n *\n * `.env` going first is what makes migrating a one-step job: add the flat file\n * and it takes over. The profile file can then be deleted whenever convenient.\n *\n * If neither file exists we skip silently — CN-hosted apps have their env\n * injected into the child process at spawn time, so there's nothing to read\n * from disk.\n */\nexport const ensureEnvironmentLoaded = async (\n environmentNames?: string[],\n): Promise<void> => {\n if (process.env.ENV_VARS_LOADED) return;\n const cwd = process.cwd();\n const envCmdrcPath = path.join(cwd, '.env-cmdrc.json');\n const dotEnvPath = path.join(cwd, '.env');\n\n // Snapshot the original shell env — it should always take priority over\n // whatever a file sets (so injected/production env wins over dev defaults).\n const shellEnv = {...process.env};\n\n const hasDotEnv = fs.existsSync(dotEnvPath);\n const hasEnvCmdrc = fs.existsSync(envCmdrcPath);\n\n for (const notice of envDeprecationNotices({hasEnvCmdrc, hasDotEnv})) {\n console.warn(chalk.yellow(notice));\n }\n\n if (hasDotEnv) {\n // Native flat-file loader (Node 20.12+). Populates process.env from `.env`.\n process.loadEnvFile(dotEnvPath);\n } else if (hasEnvCmdrc) {\n await loadEnvCmdrc(envCmdrcPath, environmentNames);\n } else {\n console.warn(\n 'No .env or .env-cmdrc.json found in this folder — relying on the ambient environment.',\n );\n }\n\n // Re-apply shell env so it always wins over file values.\n process.env = {...process.env, ...shellEnv};\n process.env.ENV_VARS_LOADED = 'true';\n};\n\n/**\n * What to tell an app about where its environment came from.\n *\n * `.env-cmdrc.json` is still read when it is the only file present, so no app\n * breaks today. But it is the only reason `--env` exists, and both are going\n * away.\n *\n * The case worth shouting about is an app holding both files: `.env` wins, so\n * the profile file and every `--env` name passed with it do nothing. That is\n * the intended migration path, but it is invisible from the outside — values\n * an app still believes it is getting from a profile are simply absent.\n *\n * Pure and exported so the messages can be asserted without a chdir.\n */\nexport const envDeprecationNotices = (sources: {\n hasEnvCmdrc: boolean;\n hasDotEnv: boolean;\n}): string[] => {\n if (!sources.hasEnvCmdrc) return [];\n const notices = [\n '.env-cmdrc.json is deprecated and will be removed in a future major release.',\n ' Move its values into a flat `.env`, and supply anything that differs per ' +\n 'deployment from the environment itself. `--env` goes away with it.',\n ];\n if (sources.hasDotEnv) {\n notices.push(\n ' This app has BOTH files. `.env` wins, so `.env-cmdrc.json` — and any ' +\n '`--env` profile named with it — is being ignored entirely. Delete it once ' +\n 'the flat file is complete.',\n );\n }\n return notices;\n};\n\n/**\n * Legacy loader: reads `.env-cmdrc.json`, merges `_main` plus the profile(s)\n * named by `--env a,b` (default `development`). Kept for CN and existing apps\n * until they migrate to a flat `.env`.\n */\nconst loadEnvCmdrc = async (\n envCmdrcPath: string,\n environmentNames?: string[],\n): Promise<void> => {\n // env-cmd ships ESM; literal specifier is fine for Vite's analyzer.\n const {GetEnvVars} = await import('env-cmd');\n const vars = await GetEnvVars({envFile: {filePath: envCmdrcPath}});\n const environments = Object.keys(vars);\n\n if (environments.includes('_main')) {\n process.env = {...process.env, ...vars._main};\n }\n // Callers that parsed `--env` themselves pass the names in. Commands that\n // have not been converted yet still have their names scraped off argv.\n const requested = environmentNames?.length\n ? environmentNames\n : readEnvNamesFromArgv();\n if (requested.length) {\n requested.forEach((name) => {\n if (environments.includes(name)) {\n console.log('Environment: ' + name);\n process.env = {...process.env, ...vars[name]};\n } else {\n console.warn(\n `Environment ${name} not found in .env-cmdrc.json. Available: ${environments.join(', ')}`,\n );\n }\n });\n } else {\n process.env = {...process.env, ...vars.development};\n console.log('No environment specified, using development');\n }\n};\n\n/**\n * Discover and load the app's storage-config bootstrap file. Tries the\n * canonical `linked.backend.storage.{ts,js}` first, then legacy paths.\n * Returns whatever the file's default export evaluates to, or undefined\n * if no candidate exists.\n */\nexport async function loadBackendStorageConfig(): Promise<any> {\n const cwd = process.cwd();\n const candidates = [\n path.join(cwd, 'linked.backend.storage.ts'),\n path.join(cwd, 'linked.backend.storage.js'),\n path.join(cwd, 'backend-storage-config.ts'),\n path.join(cwd, 'backend-storage-config.js'),\n path.join(cwd, 'scripts', 'backend-storage-config.js'),\n path.join(cwd, 'scripts', 'backend-storage-config.ts'),\n path.join(cwd, 'scripts', 'storage-config.js'),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n // Variable specifier is intentional — we discover the path at\n // runtime by probing the candidate list, so static analysis is\n // impossible.\n return import(/* @vite-ignore */ candidate);\n }\n }\n console.warn(\n chalk.yellow(\n '[linked.backend.storage] no linked.backend.storage.{ts,js} found at app root.',\n ),\n );\n return undefined;\n}\n\n/**\n * A local package directory found by {@link discoverLocalPackages}, together\n * with the facts that decide what can be done with it.\n *\n * The facts are recorded rather than filtered on, because the bug this type\n * exists to fix was a SILENT filter: `build-all` discovered only packages\n * carrying `linkedPackage: true` and printed nothing about the rest, so\n * `@_linked/maps` — a shipped dependency that simply never got the flag — was\n * dropped from a green build for as long as nobody counted the names.\n */\nexport interface LocalPackage extends PackageDetails {\n /** Where the walk found it. */\n source: 'workspace' | 'local-packages-dir';\n /** `linkedPackage: true` — see `isLinkedPackageJson`. */\n isLinkedPackage: boolean;\n /** `linkedApp: true` — built by `linked build-app`, not `linked build`. */\n isApp: boolean;\n /** Has a `build` script of its own, which is what `build-all` invokes. */\n hasBuildScript: boolean;\n}\n\n/**\n * Directory holding localized checkouts (`linked localize`). It is\n * deliberately in NO workspace glob — that is the whole point of the design,\n * since npm learning about these checkouts is what made their predecessor\n * under `packages/` a trap — so any walk of `workspaces` alone cannot see it\n * and has to be told about it separately.\n */\nexport const LOCAL_PACKAGES_DIR = 'packages-local';\n\n/**\n * Walk the app's `package.json` `workspaces` field and return every\n * workspace package that declares `\"linkedPackage\": true`.\n *\n * Lives here (not in cli-methods.ts) so consumers like LinkedServer can\n * import it without dragging the rest of the legacy cli-methods flow into\n * Vite's SSR module graph.\n *\n * Kept deliberately narrow: this is the set the dev resolver and the runtime\n * treat as linked packages. Commands that want every *buildable* local\n * package — flag or no flag, workspace or localized checkout — want\n * {@link discoverLocalPackages} instead.\n */\nexport function getLincdPackages(\n rootPath = process.cwd(),\n): PackageDetails[] {\n return discoverLocalPackages(rootPath, {includeLocalPackagesDir: false})\n .filter((pkg) => pkg.isLinkedPackage)\n .map(({path: packagePath, packageName}) => ({path: packagePath, packageName}));\n}\n\n/**\n * Every local package directory this app can see, whether or not it declares\n * `linkedPackage: true`.\n *\n * Two sources, because the workspace globs are not the whole picture any more:\n *\n * 1. the `workspaces` field (negations honoured — see ./workspace-globs.js);\n * 2. `packages-local/`, the localized checkouts, which is in no glob.\n *\n * Nothing is filtered out here. Callers decide what they can act on and are\n * expected to SAY what they skipped and why.\n */\nexport function discoverLocalPackages(\n rootPath = process.cwd(),\n options: {includeLocalPackagesDir?: boolean; localPackagesDir?: string} = {},\n): LocalPackage[] {\n const {includeLocalPackagesDir = true, localPackagesDir = LOCAL_PACKAGES_DIR} =\n options;\n\n let pack = getPackageJSON(rootPath);\n if (!pack || !pack.workspaces) {\n const originalRoot = rootPath;\n for (let i = 0; i <= 3; i++) {\n rootPath = path.join(originalRoot, ...Array(i).fill('..'));\n pack = getPackageJSON(rootPath);\n if (pack && pack.workspaces) break;\n }\n if (!pack || !pack.workspaces) {\n // Standalone apps (scaffolded with `linked create-app`) don't have\n // workspaces — expected. Fall back to the original root so a\n // `packages-local/` beside it is still found.\n rootPath = originalRoot;\n }\n }\n\n const res: LocalPackage[] = [];\n if (pack && pack.workspaces) {\n checkWorkspaces(rootPath, pack.workspaces, res);\n }\n if (includeLocalPackagesDir) {\n checkLocalPackagesDir(rootPath, localPackagesDir, res);\n }\n return res;\n}\n\n/**\n * Add every immediate subdirectory of `packages-local/` that holds a\n * `package.json`. No glob, no negations: the directory has no `workspaces`\n * entry to interpret, its contents are there because a developer localized\n * them on purpose, and each one is a plain checkout.\n */\nfunction checkLocalPackagesDir(\n rootPath: string,\n localPackagesDir: string,\n res: LocalPackage[],\n) {\n const dir = path.join(rootPath, localPackagesDir);\n if (!fs.existsSync(dir)) return;\n const already = new Set(res.map((pkg) => path.resolve(pkg.path)));\n for (const entry of fs.readdirSync(dir)) {\n if (entry.startsWith('.')) continue;\n const packagePath = path.join(dir, entry);\n if (!fs.statSync(packagePath).isDirectory()) continue;\n // A checkout that some glob already picked up must not appear twice —\n // duplicates would be built twice and counted twice.\n if (already.has(path.resolve(packagePath))) continue;\n addPackage(packagePath, 'local-packages-dir', res);\n }\n}\n\nfunction checkWorkspaces(rootPath: string, workspaces: any, res: LocalPackage[]) {\n // Negated entries (\"!packages/core\") are excluded the way npm excludes them\n // — including from the exact-path branch below, which npm also subjects to\n // them. See ./workspace-globs.js.\n const {patterns, negatedPatterns} = parseWorkspacePatterns(workspaces);\n const checkUnlessNegated = (packagePath: string) => {\n const rel = path.relative(rootPath, packagePath).split(path.sep).join('/');\n if (isWorkspacePathNegated(rel, negatedPatterns)) return;\n checkPackagePath(rootPath, packagePath, res);\n };\n patterns.forEach((workspace: string) => {\n const workspacePath = path.join(rootPath, workspace.replace('/*', ''));\n if (workspace.indexOf('/*') !== -1) {\n if (fs.existsSync(workspacePath)) {\n const folders = fs.readdirSync(workspacePath);\n folders.forEach((folder: string) => {\n if (folder !== './' && folder !== '../') {\n checkUnlessNegated(path.join(workspacePath, folder));\n }\n });\n }\n } else {\n checkUnlessNegated(workspacePath);\n }\n });\n}\n\nfunction checkPackagePath(rootPath: string, packagePath: string, res: LocalPackage[]) {\n const packageJsonPath = path.join(packagePath, 'package.json');\n if (!fs.existsSync(packageJsonPath)) return;\n const pack = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n if (pack && pack.workspaces) {\n checkWorkspaces(packagePath, pack.workspaces, res);\n } else if (pack) {\n addPackage(packagePath, 'workspace', res, pack);\n }\n}\n\nfunction addPackage(\n packagePath: string,\n source: LocalPackage['source'],\n res: LocalPackage[],\n packageJson?: any,\n) {\n const pack = packageJson ?? getPackageJSON(packagePath);\n if (!pack || !pack.name) return;\n res.push({\n path: packagePath,\n packageName: pack.name,\n source,\n // The one definition, shared with `linked build-package`.\n isLinkedPackage: isLinkedPackageJson(pack),\n isApp: pack.linkedApp === true,\n hasBuildScript: !!pack.scripts?.build,\n });\n}\n\n/**\n * Filters packages to only include those in the dependency tree of the app root\n */\nfunction filterPackagesByDependencyTree(\n allPackages: Map<string, PackageDetails>,\n appRootPath: string,\n): Map<string, PackageDetails> {\n const appPackageJson = getPackageJSON(appRootPath);\n if (!appPackageJson) {\n return allPackages;\n }\n\n const relevantPackages = new Map<string, PackageDetails>();\n const packagesToCheck = new Set<string>();\n\n // Start with direct dependencies from app root, plus everything localized:\n // a package created locally is linked but cannot be declared until it is\n // published (an unpublished range fails `npm install`), and being localized\n // already says this app is developed against it.\n [\n ...Object.keys(appPackageJson.dependencies || {}),\n ...localizedPackageNames(appRootPath),\n ].forEach((dep) => {\n if (allPackages.has(dep)) {\n packagesToCheck.add(dep);\n }\n });\n\n // Recursively add dependencies\n const processedPackages = new Set<string>();\n\n while (packagesToCheck.size > 0) {\n const packageName = Array.from(packagesToCheck)[0];\n packagesToCheck.delete(packageName);\n\n if (processedPackages.has(packageName)) {\n continue;\n }\n\n processedPackages.add(packageName);\n const packageDetails = allPackages.get(packageName);\n\n if (packageDetails) {\n relevantPackages.set(packageName, packageDetails);\n\n // Get this package's dependencies\n const packageJson = getPackageJSON(packageDetails.path);\n if (packageJson && packageJson.dependencies) {\n Object.keys(packageJson.dependencies).forEach((dep) => {\n if (allPackages.has(dep) && !processedPackages.has(dep)) {\n packagesToCheck.add(dep);\n }\n });\n }\n }\n }\n\n return relevantPackages;\n}\n\n/**\n * The package names recorded in the app's `local-packages.json` — what\n * `linked localize` has linked — read with localize's own reader. Read\n * tolerantly: `linked localize` refuses a malformed file (and warns about a\n * malformed entry) loudly, so here a missing or unusable file is simply\n * \"nothing localized\", and a malformed entry is skipped without a word.\n */\nexport function localizedPackageNames(appRootPath: string): string[] {\n try {\n return Object.keys(readManifest(appRootPath, {warn: () => {}}).entries);\n } catch {\n return [];\n }\n}\n\n/** A package `build-all` found but will not build, and why not. */\nexport interface SkippedPackage {\n packageName: string;\n path: string;\n reason: string;\n}\n\n/** What `build-all` found, and what it decided to do with each package. */\nexport interface BuildAllPlan {\n build: Map<string, PackageDetails>;\n skipped: SkippedPackage[];\n}\n\n/**\n * Decide what `build-all` builds.\n *\n * Every discovered package lands in exactly one of `build` or `skipped`, and\n * `skipped` carries a reason — because the failure mode this replaces was not\n * a narrow scan, it was a SILENT one. `@_linked/maps` is a shipped Create Now\n * dependency that never got `linkedPackage: true`; `build-all` dropped it and\n * printed nothing, so a build covering half the workspace exited 0 and people\n * acted on it. A skip nobody can see is worse than a failure.\n *\n * What counts as buildable is a CAPABILITY, not a declaration: `build-all`\n * invokes each package's own `build` script, so anything with one can be\n * built whether or not it carries the flag. The flag is still reported when\n * it is missing, since the dev resolver and `linked build` do require it.\n */\nexport function planBuildAll(rootPath = './', appRoot?: string): BuildAllPlan {\n const build = new Map<string, PackageDetails>();\n const skipped: SkippedPackage[] = [];\n const buildable: LocalPackage[] = [];\n\n for (const pkg of discoverLocalPackages(rootPath)) {\n const detail = {path: pkg.path, packageName: pkg.packageName};\n // Packages reached through a `../` workspace glob live outside this\n // repository; building them was never in scope for `build-all`.\n if (pkg.path.indexOf('../') !== -1 || pkg.path.indexOf('..\\\\') !== -1) {\n skipped.push({...detail, reason: 'outside this repository'});\n } else if (pkg.isApp) {\n skipped.push({\n ...detail,\n reason: 'is a linked app — build it with `linked build-app`',\n });\n } else if (!pkg.hasBuildScript) {\n skipped.push({...detail, reason: 'has no `build` script'});\n } else {\n buildable.push(pkg);\n build.set(pkg.packageName, detail);\n }\n }\n\n // Narrow to what this app actually depends on, if we are inside one.\n if (appRoot) {\n const appPackageJson = getPackageJSON(appRoot);\n const isAppWithLinkedDeps =\n appPackageJson &&\n !isLinkedPackageJson(appPackageJson) &&\n [\n ...Object.keys(appPackageJson.dependencies || {}),\n ...localizedPackageNames(appRoot),\n ].some((dep) => build.has(dep));\n\n if (isAppWithLinkedDeps) {\n const inTree = filterPackagesByDependencyTree(build, appRoot);\n for (const pkg of buildable) {\n if (inTree.has(pkg.packageName)) continue;\n build.delete(pkg.packageName);\n skipped.push({\n path: pkg.path,\n packageName: pkg.packageName,\n reason: `not in ${appPackageJson.name || 'this app'}'s dependency tree`,\n });\n }\n }\n }\n\n return {build, skipped};\n}\n\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type CssNamingMode = 'development' | 'production';
|
|
2
|
+
export interface LoaderModeResolution {
|
|
3
|
+
/** The NODE_ENV the CLI will run with, as far as it can be known before it loads. */
|
|
4
|
+
nodeEnv: string | undefined;
|
|
5
|
+
/** Where `nodeEnv` came from — for diagnostics and tests. */
|
|
6
|
+
source: 'shell' | '.env' | '.env-cmdrc.json' | 'vite-default' | 'unset';
|
|
7
|
+
mode: CssNamingMode;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Only `development` gets the dev names. Anything else — `production`,
|
|
11
|
+
* `staging`, unset — serves compiled output, whose stylesheet was written with
|
|
12
|
+
* the production names (see css-module-names.ts).
|
|
13
|
+
*/
|
|
14
|
+
export declare const cssNamingModeFor: (nodeEnv: string | undefined) => CssNamingMode;
|
|
15
|
+
/** `--env a,b` → `['a', 'b']`. Shared with `lifecycle.ts`, which applies the same profiles. */
|
|
16
|
+
export declare const readEnvNamesFromArgv: (argv?: string[]) => string[];
|
|
17
|
+
/**
|
|
18
|
+
* The NODE_ENV the CLI is going to run with, read the way
|
|
19
|
+
* `lifecycle.ensureEnvironmentLoaded` will apply it:
|
|
20
|
+
*
|
|
21
|
+
* 1. the shell — it always wins over a file;
|
|
22
|
+
* 2. `.env`, when present — and then `.env-cmdrc.json` is ignored entirely;
|
|
23
|
+
* 3. `.env-cmdrc.json` — `_main`, then the `--env a,b` profiles, or
|
|
24
|
+
* `development` when none are named;
|
|
25
|
+
* 4. otherwise, for `linked start`, `development`: the command serves through
|
|
26
|
+
* a Vite dev server, and Vite sets `NODE_ENV=development` itself when it is
|
|
27
|
+
* unset and writes the client with the dev names;
|
|
28
|
+
* 5. otherwise unset, which names production.
|
|
29
|
+
*
|
|
30
|
+
* Pure apart from reading the two files, so it can be tested without a launch.
|
|
31
|
+
*/
|
|
32
|
+
export declare const resolveLoaderMode: ({ env, cwd, argv, }?: {
|
|
33
|
+
env?: NodeJS.ProcessEnv;
|
|
34
|
+
cwd?: string;
|
|
35
|
+
argv?: string[];
|
|
36
|
+
}) => LoaderModeResolution;
|
|
37
|
+
//# sourceMappingURL=loader-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader-mode.d.ts","sourceRoot":"","sources":["../../src/loader-mode.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,YAAY,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC,qFAAqF;IACrF,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,6DAA6D;IAC7D,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,iBAAiB,GAAG,cAAc,GAAG,OAAO,CAAC;IACxE,IAAI,EAAE,aAAa,CAAC;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,GAAG,SAAS,KAAG,aACL,CAAC;AAE3D,+FAA+F;AAC/F,eAAO,MAAM,oBAAoB,GAC/B,OAAM,MAAM,EAAiB,KAC5B,MAAM,EAKR,CAAC;AAoBF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,GAAI,sBAI/B;IACD,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACZ,KAAG,oBAsCR,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Which CSS-module naming the Node CSS loader uses, decided before it starts.
|
|
2
|
+
//
|
|
3
|
+
// The loader (`loaders/css-loader.mts`) runs on Node's module-hooks thread,
|
|
4
|
+
// which is created by the first `register()` call in `launch.ts` and gets a
|
|
5
|
+
// COPY of `process.env` as it is at that moment. The CLI only loads the app's
|
|
6
|
+
// `.env` / `.env-cmdrc.json` afterwards (`lifecycle.ensureEnvironmentLoaded`,
|
|
7
|
+
// `commands/start.ts`), so a `NODE_ENV=development` that comes from a file never
|
|
8
|
+
// reaches the loader. It used to read `process.env.NODE_ENV` itself, saw nothing,
|
|
9
|
+
// and named every package stylesheet the production way while the dev client
|
|
10
|
+
// used the dev names: a hydration mismatch on every externalised component.
|
|
11
|
+
//
|
|
12
|
+
// So `launch.ts` resolves the mode here, on the main thread, from the same
|
|
13
|
+
// sources and in the same precedence the CLI applies later, and hands it to the
|
|
14
|
+
// loader through `register(url, {data})`. This module must stay light: it runs
|
|
15
|
+
// before the CLI itself is imported, so it uses node builtins only.
|
|
16
|
+
import fs from 'fs';
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import util from 'util';
|
|
19
|
+
/**
|
|
20
|
+
* Only `development` gets the dev names. Anything else — `production`,
|
|
21
|
+
* `staging`, unset — serves compiled output, whose stylesheet was written with
|
|
22
|
+
* the production names (see css-module-names.ts).
|
|
23
|
+
*/
|
|
24
|
+
export const cssNamingModeFor = (nodeEnv) => nodeEnv === 'development' ? 'development' : 'production';
|
|
25
|
+
/** `--env a,b` → `['a', 'b']`. Shared with `lifecycle.ts`, which applies the same profiles. */
|
|
26
|
+
export const readEnvNamesFromArgv = (argv = process.argv) => {
|
|
27
|
+
const args = argv.slice(2);
|
|
28
|
+
const envIndex = args.indexOf('--env');
|
|
29
|
+
if (envIndex === -1)
|
|
30
|
+
return [];
|
|
31
|
+
return (args[envIndex + 1] || '').split(',').filter(Boolean);
|
|
32
|
+
};
|
|
33
|
+
/** The CLI command being run: the first argument that is not an option. */
|
|
34
|
+
const commandFromArgv = (argv) => argv.slice(2).find((arg) => !arg.startsWith('-'));
|
|
35
|
+
const parseDotEnv = (source) => {
|
|
36
|
+
// `util.parseEnv` is the parser `process.loadEnvFile` uses (Node 20.12+/21.7+).
|
|
37
|
+
const parseEnv = util.parseEnv;
|
|
38
|
+
if (typeof parseEnv === 'function')
|
|
39
|
+
return parseEnv(source);
|
|
40
|
+
const vars = {};
|
|
41
|
+
for (const line of source.split(/\r?\n/)) {
|
|
42
|
+
const match = line.match(/^\s*(?:export\s+)?([\w.-]+)\s*=\s*(.*?)\s*$/);
|
|
43
|
+
if (match)
|
|
44
|
+
vars[match[1]] = match[2].replace(/^(['"`])(.*)\1$/, '$2');
|
|
45
|
+
}
|
|
46
|
+
return vars;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* The NODE_ENV the CLI is going to run with, read the way
|
|
50
|
+
* `lifecycle.ensureEnvironmentLoaded` will apply it:
|
|
51
|
+
*
|
|
52
|
+
* 1. the shell — it always wins over a file;
|
|
53
|
+
* 2. `.env`, when present — and then `.env-cmdrc.json` is ignored entirely;
|
|
54
|
+
* 3. `.env-cmdrc.json` — `_main`, then the `--env a,b` profiles, or
|
|
55
|
+
* `development` when none are named;
|
|
56
|
+
* 4. otherwise, for `linked start`, `development`: the command serves through
|
|
57
|
+
* a Vite dev server, and Vite sets `NODE_ENV=development` itself when it is
|
|
58
|
+
* unset and writes the client with the dev names;
|
|
59
|
+
* 5. otherwise unset, which names production.
|
|
60
|
+
*
|
|
61
|
+
* Pure apart from reading the two files, so it can be tested without a launch.
|
|
62
|
+
*/
|
|
63
|
+
export const resolveLoaderMode = ({ env = process.env, cwd = process.cwd(), argv = process.argv, } = {}) => {
|
|
64
|
+
var _a, _b, _c;
|
|
65
|
+
const resolved = (nodeEnv, source) => ({
|
|
66
|
+
nodeEnv,
|
|
67
|
+
source,
|
|
68
|
+
mode: cssNamingModeFor(nodeEnv),
|
|
69
|
+
});
|
|
70
|
+
if (env.NODE_ENV)
|
|
71
|
+
return resolved(env.NODE_ENV, 'shell');
|
|
72
|
+
const dotEnvPath = path.join(cwd, '.env');
|
|
73
|
+
const envCmdrcPath = path.join(cwd, '.env-cmdrc.json');
|
|
74
|
+
try {
|
|
75
|
+
if (fs.existsSync(dotEnvPath)) {
|
|
76
|
+
const fromFile = parseDotEnv(fs.readFileSync(dotEnvPath, 'utf8')).NODE_ENV;
|
|
77
|
+
if (fromFile)
|
|
78
|
+
return resolved(fromFile, '.env');
|
|
79
|
+
}
|
|
80
|
+
else if (fs.existsSync(envCmdrcPath)) {
|
|
81
|
+
const profiles = (_a = JSON.parse(fs.readFileSync(envCmdrcPath, 'utf8'))) !== null && _a !== void 0 ? _a : {};
|
|
82
|
+
const requested = readEnvNamesFromArgv(argv);
|
|
83
|
+
let fromFile = (_b = profiles._main) === null || _b === void 0 ? void 0 : _b.NODE_ENV;
|
|
84
|
+
for (const name of requested.length ? requested : ['development']) {
|
|
85
|
+
if (((_c = profiles[name]) === null || _c === void 0 ? void 0 : _c.NODE_ENV) !== undefined)
|
|
86
|
+
fromFile = profiles[name].NODE_ENV;
|
|
87
|
+
}
|
|
88
|
+
if (fromFile)
|
|
89
|
+
return resolved(String(fromFile), '.env-cmdrc.json');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (_d) {
|
|
93
|
+
// An unreadable file is reported by the CLI when it loads it; the loader
|
|
94
|
+
// falls through to the default rather than blocking the launch.
|
|
95
|
+
}
|
|
96
|
+
if (commandFromArgv(argv) === 'start')
|
|
97
|
+
return resolved('development', 'vite-default');
|
|
98
|
+
return resolved(undefined, 'unset');
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=loader-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader-mode.js","sourceRoot":"","sources":["../../src/loader-mode.ts"],"names":[],"mappings":"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","sourcesContent":["// Which CSS-module naming the Node CSS loader uses, decided before it starts.\n//\n// The loader (`loaders/css-loader.mts`) runs on Node's module-hooks thread,\n// which is created by the first `register()` call in `launch.ts` and gets a\n// COPY of `process.env` as it is at that moment. The CLI only loads the app's\n// `.env` / `.env-cmdrc.json` afterwards (`lifecycle.ensureEnvironmentLoaded`,\n// `commands/start.ts`), so a `NODE_ENV=development` that comes from a file never\n// reaches the loader. It used to read `process.env.NODE_ENV` itself, saw nothing,\n// and named every package stylesheet the production way while the dev client\n// used the dev names: a hydration mismatch on every externalised component.\n//\n// So `launch.ts` resolves the mode here, on the main thread, from the same\n// sources and in the same precedence the CLI applies later, and hands it to the\n// loader through `register(url, {data})`. This module must stay light: it runs\n// before the CLI itself is imported, so it uses node builtins only.\nimport fs from 'fs';\nimport path from 'path';\nimport util from 'util';\n\nexport type CssNamingMode = 'development' | 'production';\n\nexport interface LoaderModeResolution {\n /** The NODE_ENV the CLI will run with, as far as it can be known before it loads. */\n nodeEnv: string | undefined;\n /** Where `nodeEnv` came from — for diagnostics and tests. */\n source: 'shell' | '.env' | '.env-cmdrc.json' | 'vite-default' | 'unset';\n mode: CssNamingMode;\n}\n\n/**\n * Only `development` gets the dev names. Anything else — `production`,\n * `staging`, unset — serves compiled output, whose stylesheet was written with\n * the production names (see css-module-names.ts).\n */\nexport const cssNamingModeFor = (nodeEnv: string | undefined): CssNamingMode =>\n nodeEnv === 'development' ? 'development' : 'production';\n\n/** `--env a,b` → `['a', 'b']`. Shared with `lifecycle.ts`, which applies the same profiles. */\nexport const readEnvNamesFromArgv = (\n argv: string[] = process.argv,\n): string[] => {\n const args = argv.slice(2);\n const envIndex = args.indexOf('--env');\n if (envIndex === -1) return [];\n return (args[envIndex + 1] || '').split(',').filter(Boolean);\n};\n\n/** The CLI command being run: the first argument that is not an option. */\nconst commandFromArgv = (argv: string[]): string | undefined =>\n argv.slice(2).find((arg) => !arg.startsWith('-'));\n\nconst parseDotEnv = (source: string): Record<string, string> => {\n // `util.parseEnv` is the parser `process.loadEnvFile` uses (Node 20.12+/21.7+).\n const parseEnv = (\n util as {parseEnv?: (content: string) => Record<string, string>}\n ).parseEnv;\n if (typeof parseEnv === 'function') return parseEnv(source);\n const vars: Record<string, string> = {};\n for (const line of source.split(/\\r?\\n/)) {\n const match = line.match(/^\\s*(?:export\\s+)?([\\w.-]+)\\s*=\\s*(.*?)\\s*$/);\n if (match) vars[match[1]] = match[2].replace(/^(['\"`])(.*)\\1$/, '$2');\n }\n return vars;\n};\n\n/**\n * The NODE_ENV the CLI is going to run with, read the way\n * `lifecycle.ensureEnvironmentLoaded` will apply it:\n *\n * 1. the shell — it always wins over a file;\n * 2. `.env`, when present — and then `.env-cmdrc.json` is ignored entirely;\n * 3. `.env-cmdrc.json` — `_main`, then the `--env a,b` profiles, or\n * `development` when none are named;\n * 4. otherwise, for `linked start`, `development`: the command serves through\n * a Vite dev server, and Vite sets `NODE_ENV=development` itself when it is\n * unset and writes the client with the dev names;\n * 5. otherwise unset, which names production.\n *\n * Pure apart from reading the two files, so it can be tested without a launch.\n */\nexport const resolveLoaderMode = ({\n env = process.env,\n cwd = process.cwd(),\n argv = process.argv,\n}: {\n env?: NodeJS.ProcessEnv;\n cwd?: string;\n argv?: string[];\n} = {}): LoaderModeResolution => {\n const resolved = (\n nodeEnv: string | undefined,\n source: LoaderModeResolution['source'],\n ): LoaderModeResolution => ({\n nodeEnv,\n source,\n mode: cssNamingModeFor(nodeEnv),\n });\n\n if (env.NODE_ENV) return resolved(env.NODE_ENV, 'shell');\n\n const dotEnvPath = path.join(cwd, '.env');\n const envCmdrcPath = path.join(cwd, '.env-cmdrc.json');\n try {\n if (fs.existsSync(dotEnvPath)) {\n const fromFile = parseDotEnv(\n fs.readFileSync(dotEnvPath, 'utf8'),\n ).NODE_ENV;\n if (fromFile) return resolved(fromFile, '.env');\n } else if (fs.existsSync(envCmdrcPath)) {\n const profiles = JSON.parse(fs.readFileSync(envCmdrcPath, 'utf8')) ?? {};\n const requested = readEnvNamesFromArgv(argv);\n let fromFile: unknown = profiles._main?.NODE_ENV;\n for (const name of requested.length ? requested : ['development']) {\n if (profiles[name]?.NODE_ENV !== undefined)\n fromFile = profiles[name].NODE_ENV;\n }\n if (fromFile) return resolved(String(fromFile), '.env-cmdrc.json');\n }\n } catch {\n // An unreadable file is reported by the CLI when it loads it; the loader\n // falls through to the default rather than blocking the launch.\n }\n\n if (commandFromArgv(argv) === 'start')\n return resolved('development', 'vite-default');\n return resolved(undefined, 'unset');\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css-loader.d.mts","sourceRoot":"","sources":["../../../src/loaders/css-loader.mts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"css-loader.d.mts","sourceRoot":"","sources":["../../../src/loaders/css-loader.mts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,KAAK,aAAa,EAAC,MAAM,mBAAmB,CAAC;AASvE,wBAAsB,UAAU,CAAC,IAAI,CAAC,EAAE;IAAC,IAAI,CAAC,EAAE,aAAa,CAAA;CAAC,iBAI7D;AAiFD,eAAO,MAAO,OAAO,OAAE,IAAI,KAAiC,CAAC"}
|
|
@@ -1,7 +1,30 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import createLoader from 'create-esm-loader';
|
|
2
11
|
// import parseCSS from 'css-parse';
|
|
3
12
|
import { generateScopedName } from '../utils.js';
|
|
4
13
|
import { cssModuleExports, generateScopedNameProduction } from '../css-module-names.js';
|
|
14
|
+
import { cssNamingModeFor } from '../loader-mode.js';
|
|
15
|
+
// Which names to produce. NOT read from `process.env` at transform time: this
|
|
16
|
+
// file runs on the module-hooks thread, whose env is a copy taken when the hooks
|
|
17
|
+
// were registered — before the CLI loads the app's `.env`. `launch.ts` resolves
|
|
18
|
+
// the mode up front and passes it in through `initialize`. The env fallback only
|
|
19
|
+
// serves someone registering this loader by hand without `data`.
|
|
20
|
+
let namingMode = cssNamingModeFor(process.env.NODE_ENV);
|
|
21
|
+
export function initialize(data) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
if ((data === null || data === void 0 ? void 0 : data.mode) === 'development' || (data === null || data === void 0 ? void 0 : data.mode) === 'production') {
|
|
24
|
+
namingMode = data.mode;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
5
28
|
const cssLoader = {
|
|
6
29
|
resolve(specifier, opts) {
|
|
7
30
|
//check if the url is css
|
|
@@ -45,7 +68,8 @@ function parseCssToObject(rawSource, filename) {
|
|
|
45
68
|
// is written with Vite's. Anything but a development run serves compiled
|
|
46
69
|
// output (see startServer), so only 'development' gets the dev names — a
|
|
47
70
|
// `staging` or unset NODE_ENV must still match the production stylesheet.
|
|
48
|
-
|
|
71
|
+
// `namingMode` carries that decision (see `initialize` above).
|
|
72
|
+
const output = cssModuleExports(rawSource, filename, namingMode === 'development' ? generateScopedName : generateScopedNameProduction);
|
|
49
73
|
// console.log(myResults);
|
|
50
74
|
// for (const rule of parseCSS(rawSource).stylesheet.rules) {
|
|
51
75
|
// if(rule.selectors)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"css-loader.mjs","sourceRoot":"","sources":["../../../src/loaders/css-loader.mts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,mBAAmB,CAAC;AAC7C,oCAAoC;AACpC,OAAO,EAAC,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAC,gBAAgB,EAAE,4BAA4B,EAAC,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"css-loader.mjs","sourceRoot":"","sources":["../../../src/loaders/css-loader.mts"],"names":[],"mappings":"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","sourcesContent":["import createLoader from 'create-esm-loader';\n// import parseCSS from 'css-parse';\nimport {generateScopedName} from '../utils.js';\nimport {cssModuleExports, generateScopedNameProduction} from '../css-module-names.js';\nimport {cssNamingModeFor, type CssNamingMode} from '../loader-mode.js';\n\n// Which names to produce. NOT read from `process.env` at transform time: this\n// file runs on the module-hooks thread, whose env is a copy taken when the hooks\n// were registered — before the CLI loads the app's `.env`. `launch.ts` resolves\n// the mode up front and passes it in through `initialize`. The env fallback only\n// serves someone registering this loader by hand without `data`.\nlet namingMode: CssNamingMode = cssNamingModeFor(process.env.NODE_ENV);\n\nexport async function initialize(data?: {mode?: CssNamingMode}) {\n if (data?.mode === 'development' || data?.mode === 'production') {\n namingMode = data.mode;\n }\n}\n\nconst cssLoader = {\n resolve(specifier, opts) {\n //check if the url is css\n if (specifier.endsWith('.css')) {\n // console.log(`##LOADER option resolve ${specifier}`);\n //and not a node_module (because we don't need to process node_modules)\n if (specifier.startsWith('.')) {\n // console.log(`##LOADER resolve ${specifier} - ${specifier.startsWith('.') ? 'local' : 'node_module'}`);\n let {parentURL} = opts;\n let url = new URL(specifier, parentURL).href;\n return {url};\n } else {\n // console.log(`##LOADER NOT RESOLVING ${specifier}`);\n }\n }\n },\n format(url, opts) {\n //check if the url is css and not a node_module\n if (url.endsWith('.css')) {\n // console.log(`##LOADER format ${url} - ${url.startsWith('.') ? 'local' : 'node_module'}`);\n\n return {format: 'module'};\n }\n },\n transform(source, opts) {\n const {url} = opts;\n //check if the url is css and not a node_module\n if (url.endsWith('.css')) {\n // console.log(`##LOADER transform ${url} - ${url.startsWith('.') ? 'local' : 'node_module'}`);\n //if yes, convert the CSS source to a JSON object with original selectors as keys\n //and the converted class names as values\n let cssClassesObject = parseCssToObject(String(source), opts.url);\n let finalSource = JSON.stringify(cssClassesObject, null, 2);\n return {source: `export default ${finalSource};`};\n }\n },\n};\n\nfunction parseCssToObject(rawSource: string, filename) {\n // Must produce the names the Vite builds produce for the same file — see\n // css-module-names.ts. The server renders with these; the client's stylesheet\n // is written with Vite's. Anything but a development run serves compiled\n // output (see startServer), so only 'development' gets the dev names — a\n // `staging` or unset NODE_ENV must still match the production stylesheet.\n // `namingMode` carries that decision (see `initialize` above).\n const output = cssModuleExports(\n rawSource,\n filename,\n namingMode === 'development' ? generateScopedName : generateScopedNameProduction,\n );\n // console.log(myResults);\n // for (const rule of parseCSS(rawSource).stylesheet.rules) {\n // if(rule.selectors)\n // {\n // let selector = rule['selectors'].at(-1); // Get right-most in the selector rule: `.Bar` in `.Foo > .Bar {…}`\n // if (selector[0] !== '.') break; // only care about classes\n //\n // selector = selector\n // .substring(1) // Skip the initial `.`\n // .match(/(\\w+)/)[1]; // Get only the classname: `Qux` in `.Qux[type=\"number\"]`\n //\n // output[selector] = selector;//getClassStyles(rule['declarations']);\n // // : selector;\n // }\n // }\n\n return output;\n}\n\nfunction getClassStyles(declarations) {\n const styles = {};\n\n for (const declaration of declarations) {\n styles[declaration['property']] = declaration['value'];\n }\n\n return styles;\n}\n//@ts-ignore\nexport const {resolve, load} = await createLoader(cssLoader);\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type LoaderModeResolution } from '../loader-mode.js';
|
|
2
|
+
/**
|
|
3
|
+
* Register the CSS and TS loaders, handing the CSS loader its naming mode.
|
|
4
|
+
*
|
|
5
|
+
* The mode travels as `register()`'s one-shot `data`, not over a MessagePort,
|
|
6
|
+
* on purpose. The hooks thread caches every module it transforms, so a mode that
|
|
7
|
+
* changed after the first stylesheet was loaded would not rename that one — the
|
|
8
|
+
* process would end up with both namings at once, which is the very mismatch
|
|
9
|
+
* this exists to prevent. The mode therefore has to be fixed before any module
|
|
10
|
+
* loads and hold for the life of the process. `resolveLoaderMode` reads it from
|
|
11
|
+
* the same sources, in the same precedence, the CLI applies afterwards.
|
|
12
|
+
*/
|
|
13
|
+
export declare function registerLoaders(resolution?: LoaderModeResolution): LoaderModeResolution;
|
|
14
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/loaders/register.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,oBAAoB,EAAC,MAAM,mBAAmB,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,UAAU,GAAE,oBAA0C,GACrD,oBAAoB,CAMtB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Registers the CLI's Node module hooks. Called by `launch.ts` before the CLI is
|
|
2
|
+
// imported, so every TS/CSS file the CLI later loads from an app flows through them.
|
|
3
|
+
import { register } from 'node:module';
|
|
4
|
+
import { resolveLoaderMode } from '../loader-mode.js';
|
|
5
|
+
/**
|
|
6
|
+
* Register the CSS and TS loaders, handing the CSS loader its naming mode.
|
|
7
|
+
*
|
|
8
|
+
* The mode travels as `register()`'s one-shot `data`, not over a MessagePort,
|
|
9
|
+
* on purpose. The hooks thread caches every module it transforms, so a mode that
|
|
10
|
+
* changed after the first stylesheet was loaded would not rename that one — the
|
|
11
|
+
* process would end up with both namings at once, which is the very mismatch
|
|
12
|
+
* this exists to prevent. The mode therefore has to be fixed before any module
|
|
13
|
+
* loads and hold for the life of the process. `resolveLoaderMode` reads it from
|
|
14
|
+
* the same sources, in the same precedence, the CLI applies afterwards.
|
|
15
|
+
*/
|
|
16
|
+
export function registerLoaders(resolution = resolveLoaderMode()) {
|
|
17
|
+
register(new URL('./css-loader.mjs', import.meta.url), {
|
|
18
|
+
data: { mode: resolution.mode },
|
|
19
|
+
});
|
|
20
|
+
register(new URL('./ts-loader.mjs', import.meta.url));
|
|
21
|
+
return resolution;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/loaders/register.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,qFAAqF;AACrF,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,EAAC,iBAAiB,EAA4B,MAAM,mBAAmB,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,aAAmC,iBAAiB,EAAE;IAEtD,QAAQ,CAAC,IAAI,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QACrD,IAAI,EAAE,EAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAC;KAC9B,CAAC,CAAC;IACH,QAAQ,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["// Registers the CLI's Node module hooks. Called by `launch.ts` before the CLI is\n// imported, so every TS/CSS file the CLI later loads from an app flows through them.\nimport {register} from 'node:module';\nimport {resolveLoaderMode, type LoaderModeResolution} from '../loader-mode.js';\n\n/**\n * Register the CSS and TS loaders, handing the CSS loader its naming mode.\n *\n * The mode travels as `register()`'s one-shot `data`, not over a MessagePort,\n * on purpose. The hooks thread caches every module it transforms, so a mode that\n * changed after the first stylesheet was loaded would not rename that one — the\n * process would end up with both namings at once, which is the very mismatch\n * this exists to prevent. The mode therefore has to be fixed before any module\n * loads and hold for the life of the process. `resolveLoaderMode` reads it from\n * the same sources, in the same precedence, the CLI applies afterwards.\n */\nexport function registerLoaders(\n resolution: LoaderModeResolution = resolveLoaderMode(),\n): LoaderModeResolution {\n register(new URL('./css-loader.mjs', import.meta.url), {\n data: {mode: resolution.mode},\n });\n register(new URL('./ts-loader.mjs', import.meta.url));\n return resolution;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@_linked/cli",
|
|
3
|
-
"version": "1.45.
|
|
3
|
+
"version": "1.45.3",
|
|
4
4
|
"packageManager": "npm@11.21.0",
|
|
5
5
|
"description": "Command line tools for the @_linked/* packages and apps",
|
|
6
6
|
"main": "lib/esm/index.js",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"LICENSE"
|
|
71
71
|
],
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@_linked/core": "^2.
|
|
73
|
+
"@_linked/core": "^2.28.0",
|
|
74
74
|
"@tailwindcss/vite": "^4.1.4",
|
|
75
75
|
"@types/react": "^19.3.0",
|
|
76
76
|
"@types/react-dom": "^19.3.0",
|