@ojiepermana/angular 21.1.16 → 21.1.18
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/etos/styles/index.css +4 -12
- package/etos/styles/package.css +15 -0
- package/generator/api/bin/src/engine.js +4 -4
- package/generator/api/bin/src/layout/per-domain.js +12 -11
- package/generator/api/bin/src/writer/index.js +161 -7
- package/package.json +3 -3
- package/theme/styles/etos.css +1 -1
- package/theme/styles/themes/{taildwind.css → tailwind.css} +1 -1
package/etos/styles/index.css
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Compatibility entry for consumers that resolve the explicit index file.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Keep this publish-safe because ng-packagr copies it verbatim to
|
|
5
|
+
* `@ojiepermana/angular/etos/styles/index.css`.
|
|
5
6
|
*/
|
|
6
|
-
@import '
|
|
7
|
-
@import '../../../theme/src/lib/styles/themes/mode/index.css';
|
|
8
|
-
@import '../../../theme/src/lib/styles/themes/library/color/index.css';
|
|
9
|
-
@import '../../../theme/src/lib/styles/themes/library/style/index.css';
|
|
10
|
-
@import './color.css';
|
|
11
|
-
@import './style.css';
|
|
12
|
-
@import './layout.css';
|
|
13
|
-
@import '../../../theme/src/lib/styles/themes/library/_tokens.css';
|
|
14
|
-
@import '../../../theme/src/lib/styles/themes/library/_material-overrides.css';
|
|
15
|
-
@import '../../../theme/src/lib/styles/themes/library/_components.css';
|
|
7
|
+
@import './package.css';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ojiepermana/angular/etos — published Etos brand stylesheet.
|
|
3
|
+
*
|
|
4
|
+
* Import before Tailwind, then import the shared Tailwind token bridge.
|
|
5
|
+
*/
|
|
6
|
+
@import '@ojiepermana/angular/theme/styles/themes/library/_layers.css';
|
|
7
|
+
@import '@ojiepermana/angular/theme/styles/themes/mode/index.css';
|
|
8
|
+
@import '@ojiepermana/angular/theme/styles/themes/library/color/index.css';
|
|
9
|
+
@import '@ojiepermana/angular/theme/styles/themes/library/style/index.css';
|
|
10
|
+
@import './color.css';
|
|
11
|
+
@import './style.css';
|
|
12
|
+
@import './layout.css';
|
|
13
|
+
@import '@ojiepermana/angular/theme/styles/themes/library/_tokens.css';
|
|
14
|
+
@import '@ojiepermana/angular/theme/styles/themes/library/_material-overrides.css';
|
|
15
|
+
@import '@ojiepermana/angular/theme/styles/themes/library/_components.css';
|
|
@@ -38,8 +38,8 @@ async function generate(target, workspaceRoot) {
|
|
|
38
38
|
// public-api barrel is emitted last so it sees the final feature set.
|
|
39
39
|
files.push(...(0, public_api_1.emitPublicApi)(ir, target));
|
|
40
40
|
const laidOut = target.splitByDomain ? (0, per_domain_1.relayoutPerDomain)(files, ir, target) : files;
|
|
41
|
-
const wrapped = applyMode(laidOut, ir, target);
|
|
42
41
|
const outputDir = (0, node_path_1.isAbsolute)(target.output) ? target.output : (0, node_path_1.resolve)(workspaceRoot, target.output);
|
|
42
|
+
const wrapped = applyMode(laidOut, ir, target, workspaceRoot, outputDir);
|
|
43
43
|
return {
|
|
44
44
|
target,
|
|
45
45
|
outputDir,
|
|
@@ -52,12 +52,12 @@ async function generate(target, workspaceRoot) {
|
|
|
52
52
|
},
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
-
function applyMode(files, ir, target) {
|
|
55
|
+
function applyMode(files, ir, target, workspaceRoot, outputDir) {
|
|
56
56
|
switch (target.mode) {
|
|
57
57
|
case 'library':
|
|
58
|
-
return (0, index_1.writeLibrary)(files, ir, target);
|
|
58
|
+
return (0, index_1.writeLibrary)(files, ir, target, workspaceRoot, outputDir);
|
|
59
59
|
case 'secondary-entrypoint':
|
|
60
|
-
return (0, index_1.writeSecondaryEntrypoint)(files, ir, target);
|
|
60
|
+
return (0, index_1.writeSecondaryEntrypoint)(files, ir, target, workspaceRoot, outputDir);
|
|
61
61
|
case 'standalone':
|
|
62
62
|
default:
|
|
63
63
|
return (0, index_1.writeStandalone)(files);
|
|
@@ -293,7 +293,7 @@ function emitPublicApis(ir, target, mapping) {
|
|
|
293
293
|
}
|
|
294
294
|
if (target.features.metadata) {
|
|
295
295
|
sharedLines.push(`export * from './metadata-types';`);
|
|
296
|
-
sharedLines.push(`export * from './validators';`);
|
|
296
|
+
sharedLines.push(`export * from './validators/index';`);
|
|
297
297
|
sharedLines.push('');
|
|
298
298
|
}
|
|
299
299
|
if (target.features.navigation) {
|
|
@@ -303,16 +303,9 @@ function emitPublicApis(ir, target, mapping) {
|
|
|
303
303
|
// Per-domain public-api.ts.
|
|
304
304
|
for (const domain of mapping.domains) {
|
|
305
305
|
const lines = [target.banner, ''];
|
|
306
|
-
//
|
|
307
|
-
//
|
|
308
|
-
//
|
|
309
|
-
const domainDir = node_path_1.posix.join(VIRTUAL_ROOT, domain);
|
|
310
|
-
const sharedTarget = node_path_1.posix.join(VIRTUAL_ROOT, SHARED, 'public-api');
|
|
311
|
-
let sharedSpec = node_path_1.posix.relative(domainDir, sharedTarget);
|
|
312
|
-
if (!sharedSpec.startsWith('.'))
|
|
313
|
-
sharedSpec = `./${sharedSpec}`;
|
|
314
|
-
lines.push(`export * from '${sharedSpec}';`);
|
|
315
|
-
lines.push('');
|
|
306
|
+
// Keep each domain entrypoint scoped to its own surface. Re-exporting the
|
|
307
|
+
// shared barrel here makes the root barrel publish the same names twice
|
|
308
|
+
// once it also exports `./shared/public-api`.
|
|
316
309
|
if (target.features.models) {
|
|
317
310
|
const ownedModels = schemaNames.filter((n) => mapping.modelOwner.get(n) === domain);
|
|
318
311
|
for (const name of ownedModels) {
|
|
@@ -321,6 +314,14 @@ function emitPublicApis(ir, target, mapping) {
|
|
|
321
314
|
if (ownedModels.length)
|
|
322
315
|
lines.push('');
|
|
323
316
|
}
|
|
317
|
+
if (target.features.metadata) {
|
|
318
|
+
const tags = (mapping.domainServices.get(domain) ?? []).slice().sort();
|
|
319
|
+
for (const tag of tags) {
|
|
320
|
+
lines.push(`export { ${(0, template_1.camelCase)(tag)}OperationRules } from './permissions/${(0, template_1.kebabCase)(tag)}';`);
|
|
321
|
+
}
|
|
322
|
+
if (tags.length)
|
|
323
|
+
lines.push('');
|
|
324
|
+
}
|
|
324
325
|
if (target.features.services) {
|
|
325
326
|
const tags = mapping.domainServices.get(domain) ?? [];
|
|
326
327
|
for (const tag of tags.sort()) {
|
|
@@ -3,7 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.writeStandalone = writeStandalone;
|
|
4
4
|
exports.writeLibrary = writeLibrary;
|
|
5
5
|
exports.writeSecondaryEntrypoint = writeSecondaryEntrypoint;
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
6
8
|
const template_1 = require("../render/template");
|
|
9
|
+
const ROOT_ENTRYPOINT = '';
|
|
10
|
+
const VIRTUAL_ROOT = '/__sdk__';
|
|
7
11
|
/**
|
|
8
12
|
* No-op writer for the standalone mode — returns emitted files unchanged. Kept
|
|
9
13
|
* as a named function so modes are composable from a single switch at the
|
|
@@ -16,10 +20,11 @@ function writeStandalone(files) {
|
|
|
16
20
|
* Library mode: add `ng-package.json`, `package.json`, and a top-level README
|
|
17
21
|
* so the `output` folder can be built with ng-packagr directly.
|
|
18
22
|
*/
|
|
19
|
-
function writeLibrary(files, ir, target) {
|
|
23
|
+
function writeLibrary(files, ir, target, workspaceRoot, outputDir) {
|
|
24
|
+
const normalizedFiles = rewriteCrossEntrypointImports(files, target, workspaceRoot, outputDir);
|
|
20
25
|
const ngPackage = {
|
|
21
|
-
$schema: '
|
|
22
|
-
dest:
|
|
26
|
+
$schema: toPosixPath((0, node_path_1.relative)(outputDir, (0, node_path_1.resolve)(workspaceRoot, 'node_modules/ng-packagr/ng-package.schema.json'))),
|
|
27
|
+
dest: toPosixPath((0, node_path_1.relative)(outputDir, (0, node_path_1.resolve)(workspaceRoot, 'dist', packageSlug(target.packageName)))),
|
|
23
28
|
lib: { entryFile: 'public-api.ts' },
|
|
24
29
|
};
|
|
25
30
|
const pkg = {
|
|
@@ -34,9 +39,9 @@ function writeLibrary(files, ir, target) {
|
|
|
34
39
|
sideEffects: false,
|
|
35
40
|
};
|
|
36
41
|
return [
|
|
37
|
-
...
|
|
42
|
+
...normalizedFiles,
|
|
38
43
|
createNgPackageFile('ng-package.json', ngPackage),
|
|
39
|
-
...createNestedEntrypointNgPackages(
|
|
44
|
+
...createNestedEntrypointNgPackages(normalizedFiles),
|
|
40
45
|
{
|
|
41
46
|
path: 'package.json',
|
|
42
47
|
content: (0, template_1.finalize)(JSON.stringify(pkg, null, 2)),
|
|
@@ -53,11 +58,154 @@ function writeLibrary(files, ir, target) {
|
|
|
53
58
|
* existing library (e.g. `projects/angular/sdk-api/`) so ng-packagr picks it
|
|
54
59
|
* up automatically as a secondary entrypoint of the parent library.
|
|
55
60
|
*/
|
|
56
|
-
function writeSecondaryEntrypoint(files, _ir,
|
|
61
|
+
function writeSecondaryEntrypoint(files, _ir, target, workspaceRoot, outputDir) {
|
|
62
|
+
const normalizedFiles = rewriteCrossEntrypointImports(files, target, workspaceRoot, outputDir);
|
|
57
63
|
const ngPackage = {
|
|
58
64
|
lib: { entryFile: 'public-api.ts' },
|
|
59
65
|
};
|
|
60
|
-
return [
|
|
66
|
+
return [
|
|
67
|
+
...normalizedFiles,
|
|
68
|
+
createNgPackageFile('ng-package.json', ngPackage),
|
|
69
|
+
...createNestedEntrypointNgPackages(normalizedFiles),
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
function rewriteCrossEntrypointImports(files, target, workspaceRoot, outputDir) {
|
|
73
|
+
const entrypointDirs = collectEntrypointDirs(files);
|
|
74
|
+
if (entrypointDirs.length <= 1) {
|
|
75
|
+
return [...files];
|
|
76
|
+
}
|
|
77
|
+
const packageImportBase = resolvePackageImportBase(target, workspaceRoot, outputDir);
|
|
78
|
+
if (!packageImportBase) {
|
|
79
|
+
return [...files];
|
|
80
|
+
}
|
|
81
|
+
const knownFiles = new Set(files.map((file) => file.path));
|
|
82
|
+
return files.map((file) => {
|
|
83
|
+
const owner = findEntrypointOwner(file.path, entrypointDirs);
|
|
84
|
+
if (owner === ROOT_ENTRYPOINT) {
|
|
85
|
+
return file;
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
...file,
|
|
89
|
+
content: file.content.replace(/(from\s+['"])([^'"]+)(['"])/g, (_match, prefix, spec, suffix) => {
|
|
90
|
+
const nextSpec = rewriteModuleSpecifier(spec, file.path, owner, entrypointDirs, knownFiles, packageImportBase);
|
|
91
|
+
return `${prefix}${nextSpec}${suffix}`;
|
|
92
|
+
}),
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function rewriteModuleSpecifier(specifier, currentPath, currentOwner, entrypointDirs, knownFiles, packageImportBase) {
|
|
97
|
+
if (!specifier.startsWith('./') && !specifier.startsWith('../')) {
|
|
98
|
+
return specifier;
|
|
99
|
+
}
|
|
100
|
+
const targetPath = resolveVirtualFilePath(currentPath, specifier, knownFiles);
|
|
101
|
+
if (!targetPath) {
|
|
102
|
+
return specifier;
|
|
103
|
+
}
|
|
104
|
+
const targetOwner = findEntrypointOwner(targetPath, entrypointDirs);
|
|
105
|
+
if (targetOwner === currentOwner) {
|
|
106
|
+
return specifier;
|
|
107
|
+
}
|
|
108
|
+
return buildEntrypointImport(packageImportBase, targetOwner);
|
|
109
|
+
}
|
|
110
|
+
function resolveVirtualFilePath(currentPath, specifier, knownFiles) {
|
|
111
|
+
const currentAbs = node_path_1.posix.join(VIRTUAL_ROOT, currentPath);
|
|
112
|
+
const resolved = node_path_1.posix.normalize(node_path_1.posix.join((0, node_path_1.dirname)(currentAbs), specifier));
|
|
113
|
+
const candidates = [`${resolved}.ts`, `${resolved}/index.ts`, `${resolved}/public-api.ts`, resolved];
|
|
114
|
+
for (const candidate of candidates) {
|
|
115
|
+
if (!candidate.startsWith(`${VIRTUAL_ROOT}/`)) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const relativePath = candidate.slice(VIRTUAL_ROOT.length + 1);
|
|
119
|
+
if (knownFiles.has(relativePath)) {
|
|
120
|
+
return relativePath;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
function resolvePackageImportBase(target, workspaceRoot, outputDir) {
|
|
126
|
+
if (target.mode === 'library') {
|
|
127
|
+
return target.packageName;
|
|
128
|
+
}
|
|
129
|
+
if (target.mode !== 'secondary-entrypoint') {
|
|
130
|
+
return '';
|
|
131
|
+
}
|
|
132
|
+
return inferSecondaryEntrypointPackageName(workspaceRoot, outputDir, target.packageName);
|
|
133
|
+
}
|
|
134
|
+
function inferSecondaryEntrypointPackageName(workspaceRoot, outputDir, fallback) {
|
|
135
|
+
let currentDir = outputDir;
|
|
136
|
+
let nearestPackageDir;
|
|
137
|
+
let nearestPackagrDir;
|
|
138
|
+
while (isWithinWorkspace(currentDir, workspaceRoot)) {
|
|
139
|
+
const packageJsonPath = (0, node_path_1.resolve)(currentDir, 'package.json');
|
|
140
|
+
if ((0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
141
|
+
nearestPackageDir ??= currentDir;
|
|
142
|
+
if ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(currentDir, 'ng-package.json'))) {
|
|
143
|
+
nearestPackagrDir = currentDir;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (currentDir === workspaceRoot) {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
const parentDir = (0, node_path_1.dirname)(currentDir);
|
|
151
|
+
if (parentDir === currentDir) {
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
currentDir = parentDir;
|
|
155
|
+
}
|
|
156
|
+
const packageDir = nearestPackagrDir ?? nearestPackageDir;
|
|
157
|
+
if (!packageDir) {
|
|
158
|
+
return fallback;
|
|
159
|
+
}
|
|
160
|
+
const packageName = readPackageName(packageDir);
|
|
161
|
+
if (!packageName) {
|
|
162
|
+
return fallback;
|
|
163
|
+
}
|
|
164
|
+
const relativeOutput = toPosixPath((0, node_path_1.relative)(packageDir, outputDir)).replace(/^\.\//, '');
|
|
165
|
+
if (!relativeOutput || relativeOutput === '.') {
|
|
166
|
+
return packageName;
|
|
167
|
+
}
|
|
168
|
+
return `${packageName}/${relativeOutput}`;
|
|
169
|
+
}
|
|
170
|
+
function readPackageName(packageDir) {
|
|
171
|
+
const packageJsonPath = (0, node_path_1.resolve)(packageDir, 'package.json');
|
|
172
|
+
if (!(0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
const raw = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, 'utf8'));
|
|
176
|
+
return typeof raw.name === 'string' && raw.name.length > 0 ? raw.name : undefined;
|
|
177
|
+
}
|
|
178
|
+
function isWithinWorkspace(candidate, workspaceRoot) {
|
|
179
|
+
const rel = (0, node_path_1.relative)(workspaceRoot, candidate);
|
|
180
|
+
return rel === '' || (!rel.startsWith('..') && !(0, node_path_1.isAbsolute)(rel));
|
|
181
|
+
}
|
|
182
|
+
function collectEntrypointDirs(files) {
|
|
183
|
+
const dirs = new Set();
|
|
184
|
+
for (const file of files) {
|
|
185
|
+
if (file.path === 'public-api.ts') {
|
|
186
|
+
dirs.add(ROOT_ENTRYPOINT);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (!file.path.endsWith('/public-api.ts')) {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
dirs.add(file.path.slice(0, -'/public-api.ts'.length));
|
|
193
|
+
}
|
|
194
|
+
return [...dirs].sort((left, right) => right.length - left.length || left.localeCompare(right));
|
|
195
|
+
}
|
|
196
|
+
function findEntrypointOwner(filePath, entrypointDirs) {
|
|
197
|
+
for (const entrypointDir of entrypointDirs) {
|
|
198
|
+
if (entrypointDir === ROOT_ENTRYPOINT) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (filePath === `${entrypointDir}/public-api.ts` || filePath.startsWith(`${entrypointDir}/`)) {
|
|
202
|
+
return entrypointDir;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return ROOT_ENTRYPOINT;
|
|
206
|
+
}
|
|
207
|
+
function buildEntrypointImport(packageImportBase, entrypointDir) {
|
|
208
|
+
return entrypointDir ? `${packageImportBase}/${entrypointDir}` : packageImportBase;
|
|
61
209
|
}
|
|
62
210
|
function createNestedEntrypointNgPackages(files) {
|
|
63
211
|
return collectSecondaryEntrypointDirs(files).map((dir) => createNgPackageFile(`${dir}/ng-package.json`, {
|
|
@@ -74,6 +222,12 @@ function collectSecondaryEntrypointDirs(files) {
|
|
|
74
222
|
}
|
|
75
223
|
return [...dirs].sort();
|
|
76
224
|
}
|
|
225
|
+
function packageSlug(packageName) {
|
|
226
|
+
return packageName.replace(/^@/, '').replace(/\//g, '-');
|
|
227
|
+
}
|
|
228
|
+
function toPosixPath(value) {
|
|
229
|
+
return value.split('\\').join('/');
|
|
230
|
+
}
|
|
77
231
|
function createNgPackageFile(path, content) {
|
|
78
232
|
return {
|
|
79
233
|
path,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ojiepermana/angular",
|
|
3
|
-
"version": "21.1.
|
|
3
|
+
"version": "21.1.18",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/ojiepermana/angular.git"
|
|
@@ -65,11 +65,11 @@
|
|
|
65
65
|
"sideEffects": false,
|
|
66
66
|
"schematics": "./collection.json",
|
|
67
67
|
"exports": {
|
|
68
|
-
"./etos/styles": "./etos/styles/
|
|
68
|
+
"./etos/styles": "./etos/styles/package.css",
|
|
69
69
|
"./etos/styles/*": "./etos/styles/*",
|
|
70
70
|
"./theme/styles": "./theme/styles/index.css",
|
|
71
71
|
"./theme/styles/*": "./theme/styles/*",
|
|
72
|
-
"./theme/tailwind/theme.css": "./theme/styles/themes/
|
|
72
|
+
"./theme/tailwind/theme.css": "./theme/styles/themes/tailwind.css",
|
|
73
73
|
"./package.json": {
|
|
74
74
|
"default": "./package.json"
|
|
75
75
|
},
|
package/theme/styles/etos.css
CHANGED