wexample-wex-addon-dev-javascript 7.16.0__tar.gz → 8.0.0__tar.gz
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.
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/PKG-INFO +6 -6
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/README.md +3 -3
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/pyproject.toml +3 -3
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/file/javascript_package_json_file.py +11 -60
- wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/file/node_package_json_file.py +75 -0
- {wexample_wex_addon_dev_javascript-7.16.0/src/wexample_wex_addon_dev_javascript/services/vite → wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/services/node/commands}/__init__.py +0 -0
- wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/services/node/commands/service/install_local.py +81 -0
- wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/services/node/commands/service/refresh_lock.py +66 -0
- {wexample_wex_addon_dev_javascript-7.16.0/src/wexample_wex_addon_dev_javascript/services/vite/ai/agents → wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/services/vite}/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0/src/wexample_wex_addon_dev_javascript/services/vite/commands → wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/services/vite/ai/agents}/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0/src/wexample_wex_addon_dev_javascript/services/vite/commands/service → wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/services/vite/ai/agents/main}/__init__.py +0 -0
- wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/services/vite/commands/service/__init__.py +0 -0
- wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/workdir/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/workdir/javascript_package_workdir.py +38 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/common/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/common/npm_registry_gateway.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/config_value/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/config_value/javascript_package_readme_config_value.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/const/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/const/tags.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/file/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/file/javascript_tsconfig_json_file.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/javascript_addon_manager.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/py.typed +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/resources/.wex.yml +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/resources/package_publish.yml +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/node/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0/src/wexample_wex_addon_dev_javascript/services/vite/ai → wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/services/node/commands/service}/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/node/docker/.wex.yml +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/node/docker/docker-compose.yml +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/node/service.yml +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0/src/wexample_wex_addon_dev_javascript/services/vite/ai/agents/main → wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/services/vite/ai}/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/vite/ai/agents/main/about-service.md +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/vite/ai/agents/main/agent.yml +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/vite/app_service.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0/src/wexample_wex_addon_dev_javascript/workdir → wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/services/vite/commands}/__init__.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/vite/commands/service/install.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/vite/commands/service/ready.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/vite/docker/.wex.yml +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/vite/docker/docker-compose.yml +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/services/vite/service.yml +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/workdir/javascript_packages_suite_workdir.py +0 -0
- {wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/src/wexample_wex_addon_dev_javascript/workdir/javascript_workdir.py +0 -0
{wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wexample-wex-addon-dev-javascript
|
|
3
|
-
Version:
|
|
3
|
+
Version: 8.0.0
|
|
4
4
|
Summary: Python dev addon for wex
|
|
5
5
|
Author-Email: weeger <contact@wexample.com>
|
|
6
6
|
License: MIT
|
|
@@ -13,8 +13,8 @@ Requires-Dist: attrs>=23.1.0
|
|
|
13
13
|
Requires-Dist: cattrs>=23.1.0
|
|
14
14
|
Requires-Dist: wexample-api>=6.8.0
|
|
15
15
|
Requires-Dist: wexample-filestate-javascript>=6.6.0
|
|
16
|
-
Requires-Dist: wexample-wex-addon-ai>=12.
|
|
17
|
-
Requires-Dist: wexample-wex-addon-app>=
|
|
16
|
+
Requires-Dist: wexample-wex-addon-ai>=12.1.0
|
|
17
|
+
Requires-Dist: wexample-wex-addon-app>=29.0.0
|
|
18
18
|
Provides-Extra: dev
|
|
19
19
|
Requires-Dist: pytest; extra == "dev"
|
|
20
20
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -22,7 +22,7 @@ Description-Content-Type: text/markdown
|
|
|
22
22
|
|
|
23
23
|
# wex_addon_dev_javascript
|
|
24
24
|
|
|
25
|
-
Version:
|
|
25
|
+
Version: 8.0.0
|
|
26
26
|
|
|
27
27
|
Python dev addon for wex
|
|
28
28
|
|
|
@@ -106,8 +106,8 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
106
106
|
- cattrs: >=23.1.0
|
|
107
107
|
- wexample-api: >=6.8.0
|
|
108
108
|
- wexample-filestate-javascript: >=6.6.0
|
|
109
|
-
- wexample-wex-addon-ai: >=12.
|
|
110
|
-
- wexample-wex-addon-app: >=
|
|
109
|
+
- wexample-wex-addon-ai: >=12.1.0
|
|
110
|
+
- wexample-wex-addon-app: >=29.0.0
|
|
111
111
|
|
|
112
112
|
## Versioning & Compatibility Policy
|
|
113
113
|
|
{wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/README.md
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# wex_addon_dev_javascript
|
|
2
2
|
|
|
3
|
-
Version:
|
|
3
|
+
Version: 8.0.0
|
|
4
4
|
|
|
5
5
|
Python dev addon for wex
|
|
6
6
|
|
|
@@ -84,8 +84,8 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
84
84
|
- cattrs: >=23.1.0
|
|
85
85
|
- wexample-api: >=6.8.0
|
|
86
86
|
- wexample-filestate-javascript: >=6.6.0
|
|
87
|
-
- wexample-wex-addon-ai: >=12.
|
|
88
|
-
- wexample-wex-addon-app: >=
|
|
87
|
+
- wexample-wex-addon-ai: >=12.1.0
|
|
88
|
+
- wexample-wex-addon-app: >=29.0.0
|
|
89
89
|
|
|
90
90
|
## Versioning & Compatibility Policy
|
|
91
91
|
|
{wexample_wex_addon_dev_javascript-7.16.0 → wexample_wex_addon_dev_javascript-8.0.0}/pyproject.toml
RENAMED
|
@@ -6,7 +6,7 @@ build-backend = "pdm.backend"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "wexample-wex-addon-dev-javascript"
|
|
9
|
-
version = "
|
|
9
|
+
version = "8.0.0"
|
|
10
10
|
description = "Python dev addon for wex"
|
|
11
11
|
authors = [
|
|
12
12
|
{ name = "weeger", email = "contact@wexample.com" },
|
|
@@ -22,8 +22,8 @@ dependencies = [
|
|
|
22
22
|
"cattrs>=23.1.0",
|
|
23
23
|
"wexample-api>=6.8.0",
|
|
24
24
|
"wexample-filestate-javascript>=6.6.0",
|
|
25
|
-
"wexample-wex-addon-ai>=12.
|
|
26
|
-
"wexample-wex-addon-app>=
|
|
25
|
+
"wexample-wex-addon-ai>=12.1.0",
|
|
26
|
+
"wexample-wex-addon-app>=29.0.0",
|
|
27
27
|
]
|
|
28
28
|
|
|
29
29
|
[project.readme]
|
|
@@ -1,60 +1,21 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from wexample_filestate.item.file.json_file import JsonFile
|
|
4
3
|
from wexample_helpers.decorator.base_class import base_class
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
from wexample_wex_addon_dev_javascript.file.node_package_json_file import (
|
|
6
|
+
NodePackageJsonFile,
|
|
7
7
|
)
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@base_class
|
|
11
|
-
class JavascriptPackageJsonFile(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
operator=operator,
|
|
20
|
-
**kwargs,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
def add_dependency_from_string(
|
|
24
|
-
self,
|
|
25
|
-
package_name: str,
|
|
26
|
-
version: str,
|
|
27
|
-
operator: str = "",
|
|
28
|
-
optional: bool = False,
|
|
29
|
-
group: None | str = None,
|
|
30
|
-
) -> bool:
|
|
31
|
-
"""
|
|
32
|
-
Add or update an npm dependency entry from a raw package name + version string.
|
|
33
|
-
Equivalent to add_dependency() but without requiring a CodeBaseWorkdir.
|
|
34
|
-
"""
|
|
35
|
-
if optional:
|
|
36
|
-
section = "optionalDependencies"
|
|
37
|
-
elif group == "dev":
|
|
38
|
-
section = "devDependencies"
|
|
39
|
-
elif group:
|
|
40
|
-
section = group
|
|
41
|
-
else:
|
|
42
|
-
section = "dependencies"
|
|
43
|
-
|
|
44
|
-
constraint = f"{operator}{version}".strip()
|
|
45
|
-
|
|
46
|
-
config = self.read_config()
|
|
47
|
-
deps_node = config.search(path=section, default={})
|
|
48
|
-
deps = deps_node.to_dict() if deps_node else {}
|
|
49
|
-
|
|
50
|
-
if deps.get(package_name) == constraint:
|
|
51
|
-
return False
|
|
52
|
-
|
|
53
|
-
deps[package_name] = constraint
|
|
54
|
-
config.update_nested({section: deps})
|
|
55
|
-
self.write_config(config)
|
|
56
|
-
|
|
57
|
-
return True
|
|
11
|
+
class JavascriptPackageJsonFile(NodePackageJsonFile):
|
|
12
|
+
"""A published javascript package's package.json.
|
|
13
|
+
|
|
14
|
+
On top of the dependency-manifest API, publication metadata (name,
|
|
15
|
+
version, repository, publishConfig, exports...) is derived from the
|
|
16
|
+
workdir at dump time — which is why this class must never be attached
|
|
17
|
+
to an app manifest (see NodePackageJsonFile).
|
|
18
|
+
"""
|
|
58
19
|
|
|
59
20
|
def dumps(self, content: dict | None = None) -> str:
|
|
60
21
|
content = content or self.read_parsed()
|
|
@@ -71,16 +32,6 @@ class JavascriptPackageJsonFile(AppDependenciesConfigFileMixin, JsonFile):
|
|
|
71
32
|
|
|
72
33
|
return super().dumps(content)
|
|
73
34
|
|
|
74
|
-
def get_dependencies_versions(
|
|
75
|
-
self, optional: bool = False, group: str = "dev"
|
|
76
|
-
) -> dict[str, str]:
|
|
77
|
-
config = self.read_config()
|
|
78
|
-
# Use to_dict_or_none() (not get_dict_or_default) so nested ConfigValue
|
|
79
|
-
# wrappers are unwrapped to native str — matches the dict[str, str] signature.
|
|
80
|
-
deps = config.search(path="dependencies").to_dict_or_none() or {}
|
|
81
|
-
peer = config.search(path="peerDependencies").to_dict_or_none() or {}
|
|
82
|
-
return {**deps, **peer}
|
|
83
|
-
|
|
84
35
|
def _apply_default_publish_config(self, content: dict) -> None:
|
|
85
36
|
content.setdefault("type", "module")
|
|
86
37
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from wexample_filestate.item.file.json_file import JsonFile
|
|
4
|
+
from wexample_helpers.decorator.base_class import base_class
|
|
5
|
+
from wexample_wex_addon_app.item.file.mixin.app_dependencies_config_file_mixin import (
|
|
6
|
+
AppDependenciesConfigFileMixin,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@base_class
|
|
11
|
+
class NodePackageJsonFile(AppDependenciesConfigFileMixin, JsonFile):
|
|
12
|
+
"""A package.json exposing the dependency-manifest API.
|
|
13
|
+
|
|
14
|
+
Suits any workdir shipping a package.json (polyglot apps included);
|
|
15
|
+
JavascriptPackageJsonFile extends it with package-publication concerns
|
|
16
|
+
(name/version stamping, publishConfig...) that must never touch an
|
|
17
|
+
app manifest.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def add_dependency(
|
|
21
|
+
self,
|
|
22
|
+
operator: str = "",
|
|
23
|
+
**kwargs,
|
|
24
|
+
) -> bool:
|
|
25
|
+
# NPM uses bare versions (or ^/~), not "==".
|
|
26
|
+
return super().add_dependency(
|
|
27
|
+
operator=operator,
|
|
28
|
+
**kwargs,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
def add_dependency_from_string(
|
|
32
|
+
self,
|
|
33
|
+
package_name: str,
|
|
34
|
+
version: str,
|
|
35
|
+
operator: str = "",
|
|
36
|
+
optional: bool = False,
|
|
37
|
+
group: None | str = None,
|
|
38
|
+
) -> bool:
|
|
39
|
+
"""
|
|
40
|
+
Add or update an npm dependency entry from a raw package name + version string.
|
|
41
|
+
Equivalent to add_dependency() but without requiring a CodeBaseWorkdir.
|
|
42
|
+
"""
|
|
43
|
+
if optional:
|
|
44
|
+
section = "optionalDependencies"
|
|
45
|
+
elif group == "dev":
|
|
46
|
+
section = "devDependencies"
|
|
47
|
+
elif group:
|
|
48
|
+
section = group
|
|
49
|
+
else:
|
|
50
|
+
section = "dependencies"
|
|
51
|
+
|
|
52
|
+
constraint = f"{operator}{version}".strip()
|
|
53
|
+
|
|
54
|
+
config = self.read_config()
|
|
55
|
+
deps_node = config.search(path=section, default={})
|
|
56
|
+
deps = deps_node.to_dict() if deps_node else {}
|
|
57
|
+
|
|
58
|
+
if deps.get(package_name) == constraint:
|
|
59
|
+
return False
|
|
60
|
+
|
|
61
|
+
deps[package_name] = constraint
|
|
62
|
+
config.update_nested({section: deps})
|
|
63
|
+
self.write_config(config)
|
|
64
|
+
|
|
65
|
+
return True
|
|
66
|
+
|
|
67
|
+
def get_dependencies_versions(
|
|
68
|
+
self, optional: bool = False, group: str = "dev"
|
|
69
|
+
) -> dict[str, str]:
|
|
70
|
+
config = self.read_config()
|
|
71
|
+
# Use to_dict_or_none() (not get_dict_or_default) so nested ConfigValue
|
|
72
|
+
# wrappers are unwrapped to native str — matches the dict[str, str] signature.
|
|
73
|
+
deps = config.search(path="dependencies").to_dict_or_none() or {}
|
|
74
|
+
peer = config.search(path="peerDependencies").to_dict_or_none() or {}
|
|
75
|
+
return {**deps, **peer}
|
|
File without changes
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from wexample_cli.const.tags import AudienceTag, EffectTag, ScopeTag
|
|
6
|
+
from wexample_cli.decorator.command import command
|
|
7
|
+
from wexample_wex_core.const.globals import COMMAND_TYPE_SERVICE
|
|
8
|
+
|
|
9
|
+
from wexample_wex_addon_dev_javascript.const.tags import DomainTag
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from wexample_cli.context.execution_context import ExecutionContext
|
|
13
|
+
from wexample_wex_addon_app.service.app_service import AppService
|
|
14
|
+
|
|
15
|
+
# In-container layout convention shared by the local dev composes: the app is
|
|
16
|
+
# served from APP_DIR and each locally-developed javascript suite is mounted
|
|
17
|
+
# under JS_DEV_DIR/<vendor> (see the `local_packages` env config section).
|
|
18
|
+
APP_DIR = "/var/www/html"
|
|
19
|
+
JS_DEV_DIR = "/var/www/javascript-dev"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@command(
|
|
23
|
+
type=COMMAND_TYPE_SERVICE,
|
|
24
|
+
description="Wire locally-developed npm packages into node_modules/ (local env only)",
|
|
25
|
+
tags=[
|
|
26
|
+
DomainTag.FRONTEND,
|
|
27
|
+
EffectTag.WRITE,
|
|
28
|
+
AudienceTag.AGENT_SAFE,
|
|
29
|
+
ScopeTag.APP,
|
|
30
|
+
ScopeTag.CONTAINER,
|
|
31
|
+
ScopeTag.LOCAL,
|
|
32
|
+
],
|
|
33
|
+
)
|
|
34
|
+
def node__service__install_local(
|
|
35
|
+
context: ExecutionContext,
|
|
36
|
+
service: AppService,
|
|
37
|
+
) -> None:
|
|
38
|
+
"""Generic node_modules wiring, reusable by any service whose container
|
|
39
|
+
runs the app's javascript toolchain (symfony, laravel, vite…).
|
|
40
|
+
|
|
41
|
+
Delegating services call this with their own ``service`` so the work runs
|
|
42
|
+
inside their container.
|
|
43
|
+
"""
|
|
44
|
+
js_packages = service.app_workdir.get_runtime_config().search(
|
|
45
|
+
"local_packages.javascript"
|
|
46
|
+
)
|
|
47
|
+
if js_packages.is_none():
|
|
48
|
+
context.io.log("No local_packages.javascript configured, nothing to wire.")
|
|
49
|
+
return
|
|
50
|
+
|
|
51
|
+
vendors = " ".join(sorted(js_packages.to_dict().keys()))
|
|
52
|
+
|
|
53
|
+
# Package managers keep the (possibly stale) registry version even when a
|
|
54
|
+
# newer local source exists, so the deterministic wiring is a forced
|
|
55
|
+
# symlink over node_modules/ — resolved by each package's declared scoped
|
|
56
|
+
# name, which differs from its directory name.
|
|
57
|
+
script = f"""
|
|
58
|
+
set -e
|
|
59
|
+
cd {APP_DIR}
|
|
60
|
+
if [ -f yarn.lock ]; then yarn install
|
|
61
|
+
elif [ -f pnpm-lock.yaml ]; then pnpm install
|
|
62
|
+
else npm install
|
|
63
|
+
fi
|
|
64
|
+
for vendor in {vendors}; do
|
|
65
|
+
[ -d "{JS_DEV_DIR}/$vendor" ] || continue
|
|
66
|
+
for src in {JS_DEV_DIR}/$vendor/*/; do
|
|
67
|
+
[ -f "$src/package.json" ] || continue
|
|
68
|
+
name=$(node -p "require('$src/package.json').name")
|
|
69
|
+
mkdir -p "node_modules/$(dirname "$name")"
|
|
70
|
+
rm -rf "node_modules/$name"
|
|
71
|
+
ln -s "${{src%/}}" "node_modules/$name"
|
|
72
|
+
echo " symlinked $name"
|
|
73
|
+
done
|
|
74
|
+
done
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
context.io.log(f"Wiring local npm packages ({vendors}) into node_modules/…")
|
|
78
|
+
output = service.addon_manager.docker_exec(
|
|
79
|
+
service.name, ["/bin/sh", "-c", script]
|
|
80
|
+
)
|
|
81
|
+
context.io.log(output)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from wexample_cli.const.tags import AudienceTag, EffectTag, ScopeTag
|
|
6
|
+
from wexample_cli.decorator.command import command
|
|
7
|
+
from wexample_cli.decorator.option import option
|
|
8
|
+
from wexample_wex_core.const.globals import COMMAND_TYPE_SERVICE
|
|
9
|
+
|
|
10
|
+
from wexample_wex_addon_dev_javascript.const.tags import DomainTag
|
|
11
|
+
from wexample_wex_addon_dev_javascript.services.node.commands.service.install_local import (
|
|
12
|
+
APP_DIR,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from wexample_cli.context.execution_context import ExecutionContext
|
|
17
|
+
from wexample_wex_addon_app.service.app_service import AppService
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@option(
|
|
21
|
+
name="npm_packages",
|
|
22
|
+
type=str,
|
|
23
|
+
required=True,
|
|
24
|
+
description="Space-separated npm package names whose constraint changed in package.json",
|
|
25
|
+
)
|
|
26
|
+
@command(
|
|
27
|
+
type=COMMAND_TYPE_SERVICE,
|
|
28
|
+
description="Refresh the javascript lock file after a package.json dependency change",
|
|
29
|
+
tags=[
|
|
30
|
+
DomainTag.FRONTEND,
|
|
31
|
+
EffectTag.WRITE,
|
|
32
|
+
AudienceTag.AGENT_SAFE,
|
|
33
|
+
ScopeTag.APP,
|
|
34
|
+
ScopeTag.CONTAINER,
|
|
35
|
+
ScopeTag.LOCAL,
|
|
36
|
+
],
|
|
37
|
+
)
|
|
38
|
+
def node__service__refresh_lock(
|
|
39
|
+
context: ExecutionContext,
|
|
40
|
+
service: AppService,
|
|
41
|
+
npm_packages: str,
|
|
42
|
+
) -> None:
|
|
43
|
+
"""Generic javascript lock refresh, reusable by any service whose
|
|
44
|
+
container runs the app's javascript toolchain.
|
|
45
|
+
|
|
46
|
+
The lock file present in the app tells which package manager owns it.
|
|
47
|
+
Yarn classic has no lock-only mode, so node_modules is (re)installed
|
|
48
|
+
along the way — harmless inside the app container.
|
|
49
|
+
"""
|
|
50
|
+
script = f"""
|
|
51
|
+
set -e
|
|
52
|
+
cd {APP_DIR}
|
|
53
|
+
if [ -f yarn.lock ]; then yarn install
|
|
54
|
+
elif [ -f pnpm-lock.yaml ]; then pnpm install --lockfile-only
|
|
55
|
+
elif [ -f package-lock.json ]; then npm install --package-lock-only
|
|
56
|
+
else
|
|
57
|
+
echo "No javascript lock file found in {APP_DIR}" >&2
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
context.io.log(f"Refreshing javascript lock file ({npm_packages})…")
|
|
63
|
+
output = service.addon_manager.docker_exec(
|
|
64
|
+
service.name, ["/bin/sh", "-c", script]
|
|
65
|
+
)
|
|
66
|
+
context.io.log(output)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
wexample_wex_addon_dev_javascript-8.0.0/src/wexample_wex_addon_dev_javascript/workdir/__init__.py
ADDED
|
File without changes
|
|
@@ -35,6 +35,14 @@ class JavascriptPackageWorkdir(JavascriptWorkdir):
|
|
|
35
35
|
def get_project_name(self) -> str:
|
|
36
36
|
return f"@{self.get_vendor_name()}/{string_to_kebab_case(super().get_project_name())}"
|
|
37
37
|
|
|
38
|
+
# Lockfile → package manager + its lockfile-only refresh command. The
|
|
39
|
+
# lockfile present in the repo tells which manager the project uses.
|
|
40
|
+
_LOCKFILE_REFRESH_COMMANDS: dict[str, list[str]] = {
|
|
41
|
+
"package-lock.json": ["npm", "install", "--package-lock-only"],
|
|
42
|
+
"pnpm-lock.yaml": ["pnpm", "install", "--lockfile-only"],
|
|
43
|
+
"yarn.lock": ["yarn", "install", "--mode", "update-lockfile"],
|
|
44
|
+
}
|
|
45
|
+
|
|
38
46
|
def prepare_value(self, raw_value: DictConfig | None = None) -> DictConfig:
|
|
39
47
|
from wexample_filestate.const.disk import DiskItemType
|
|
40
48
|
from wexample_helpers.helper.file import file_read
|
|
@@ -76,8 +84,20 @@ class JavascriptPackageWorkdir(JavascriptWorkdir):
|
|
|
76
84
|
|
|
77
85
|
return raw_value
|
|
78
86
|
|
|
87
|
+
def release(self, **kwargs) -> None:
|
|
88
|
+
# The lockfile must follow package.json: CI installs run in strict
|
|
89
|
+
# mode (`npm ci` & co) and fail hard on any desync between the two.
|
|
90
|
+
# A sibling's propagate step may have bumped constraints here, so the
|
|
91
|
+
# refresh happens at release start — NOT at propagate time, when the
|
|
92
|
+
# sibling's new version is not registry-available yet (it publishes,
|
|
93
|
+
# then waits for the registry, before dependents release: the suite
|
|
94
|
+
# loop follows the dependency graph).
|
|
95
|
+
self._refresh_lockfile()
|
|
96
|
+
return super().release(**kwargs)
|
|
97
|
+
|
|
79
98
|
def _classify_version_bump(self, last_tag: str) -> str:
|
|
80
99
|
from wexample_helpers.const.types import (
|
|
100
|
+
UPGRADE_TYPE_INTERMEDIATE,
|
|
81
101
|
UPGRADE_TYPE_MAJOR,
|
|
82
102
|
UPGRADE_TYPE_MINOR,
|
|
83
103
|
)
|
|
@@ -147,6 +167,24 @@ class JavascriptPackageWorkdir(JavascriptWorkdir):
|
|
|
147
167
|
|
|
148
168
|
git_push_tag(tag, cwd=cwd, remote=remote, inherit_stdio=True)
|
|
149
169
|
|
|
170
|
+
def _refresh_lockfile(self) -> None:
|
|
171
|
+
import shutil
|
|
172
|
+
|
|
173
|
+
from wexample_helpers.helper.shell import shell_run
|
|
174
|
+
|
|
175
|
+
for lockfile, command in self._LOCKFILE_REFRESH_COMMANDS.items():
|
|
176
|
+
if not (self.get_path() / lockfile).exists():
|
|
177
|
+
continue
|
|
178
|
+
if shutil.which(command[0]) is None:
|
|
179
|
+
raise RuntimeError(
|
|
180
|
+
f"{lockfile} needs a refresh after a dependency change in "
|
|
181
|
+
f"{self.get_project_name()}, but '{command[0]}' is not "
|
|
182
|
+
f"available on this machine. A stale lockfile would break "
|
|
183
|
+
f"the strict CI install."
|
|
184
|
+
)
|
|
185
|
+
shell_run(command, cwd=self.get_path())
|
|
186
|
+
return
|
|
187
|
+
|
|
150
188
|
def _wait_for_registry(self) -> None:
|
|
151
189
|
"""Poll the configured npm registry until the current version is available (max 20 min).
|
|
152
190
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|