@ojiepermana/angular 21.1.16 → 21.1.17

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.
@@ -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) {
@@ -321,6 +321,14 @@ function emitPublicApis(ir, target, mapping) {
321
321
  if (ownedModels.length)
322
322
  lines.push('');
323
323
  }
324
+ if (target.features.metadata) {
325
+ const tags = (mapping.domainServices.get(domain) ?? []).slice().sort();
326
+ for (const tag of tags) {
327
+ lines.push(`export { ${(0, template_1.camelCase)(tag)}OperationRules } from './permissions/${(0, template_1.kebabCase)(tag)}';`);
328
+ }
329
+ if (tags.length)
330
+ lines.push('');
331
+ }
324
332
  if (target.features.services) {
325
333
  const tags = mapping.domainServices.get(domain) ?? [];
326
334
  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: '../../node_modules/ng-packagr/ng-package.schema.json',
22
- dest: `../dist/${target.packageName.replace(/^@/, '').replace(/\//g, '-')}`,
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
- ...files,
42
+ ...normalizedFiles,
38
43
  createNgPackageFile('ng-package.json', ngPackage),
39
- ...createNestedEntrypointNgPackages(files),
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, _target) {
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 [...files, createNgPackageFile('ng-package.json', ngPackage), ...createNestedEntrypointNgPackages(files)];
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.16",
3
+ "version": "21.1.17",
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/index.css",
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/taildwind.css",
72
+ "./theme/tailwind/theme.css": "./theme/styles/themes/tailwind.css",
73
73
  "./package.json": {
74
74
  "default": "./package.json"
75
75
  },
@@ -3,4 +3,4 @@
3
3
  *
4
4
  * The Etos implementation now lives under the dedicated `./etos` entrypoint.
5
5
  */
6
- @import '../../../../brand/etos/themes/index.css';
6
+ @import '@ojiepermana/angular/etos/styles';
@@ -109,4 +109,4 @@
109
109
 
110
110
  --font-sans: var(--theme-font-sans);
111
111
  --font-mono: var(--theme-font-mono);
112
- }
112
+ }