@kitsy/cnos 0.0.1 → 1.0.0

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.
Files changed (47) hide show
  1. package/README.md +3 -1
  2. package/dist/chunk-BSETFXI3.js +23 -0
  3. package/dist/chunk-BSOPGV7G.js +49 -0
  4. package/dist/chunk-D7AYK7X5.js +8899 -0
  5. package/dist/chunk-I6QXNQEF.js +202 -0
  6. package/dist/chunk-QNGS4HFP.js +109 -0
  7. package/dist/chunk-TYA4BNYT.js +83 -0
  8. package/dist/chunk-V4LCFDBY.js +35 -0
  9. package/dist/envNaming-BrOk5ndZ.d.cts +8 -0
  10. package/dist/envNaming-DCaNdnrF.d.ts +8 -0
  11. package/dist/index.cjs +9244 -28
  12. package/dist/index.d.cts +7 -3
  13. package/dist/index.d.ts +7 -3
  14. package/dist/index.js +109 -23
  15. package/dist/internal.cjs +7593 -0
  16. package/dist/internal.d.cts +20 -0
  17. package/dist/internal.d.ts +20 -0
  18. package/dist/internal.js +18 -0
  19. package/dist/plugin/basic-schema.cjs +7519 -3
  20. package/dist/plugin/basic-schema.d.cts +5 -6
  21. package/dist/plugin/basic-schema.d.ts +5 -6
  22. package/dist/plugin/basic-schema.js +7 -2
  23. package/dist/plugin/cli-args.cjs +7437 -3
  24. package/dist/plugin/cli-args.d.cts +12 -1
  25. package/dist/plugin/cli-args.d.ts +12 -1
  26. package/dist/plugin/cli-args.js +11 -2
  27. package/dist/plugin/dotenv.cjs +7517 -3
  28. package/dist/plugin/dotenv.d.cts +8 -1
  29. package/dist/plugin/dotenv.d.ts +8 -1
  30. package/dist/plugin/dotenv.js +11 -2
  31. package/dist/plugin/env-export.cjs +7527 -3
  32. package/dist/plugin/env-export.d.cts +7 -1
  33. package/dist/plugin/env-export.d.ts +7 -1
  34. package/dist/plugin/env-export.js +14 -2
  35. package/dist/plugin/filesystem.cjs +7625 -3
  36. package/dist/plugin/filesystem.d.cts +17 -1
  37. package/dist/plugin/filesystem.d.ts +17 -1
  38. package/dist/plugin/filesystem.js +17 -2
  39. package/dist/plugin/process-env.cjs +7431 -3
  40. package/dist/plugin/process-env.d.cts +7 -1
  41. package/dist/plugin/process-env.d.ts +7 -1
  42. package/dist/plugin/process-env.js +9 -2
  43. package/dist/plugin-BVNEHj19.d.cts +309 -0
  44. package/dist/plugin-BVNEHj19.d.ts +309 -0
  45. package/dist/toPublicEnv-Dd152fFy.d.cts +7 -0
  46. package/dist/toPublicEnv-Gwz3xTK0.d.ts +7 -0
  47. package/package.json +14 -18
@@ -0,0 +1,202 @@
1
+ import {
2
+ CnosManifestError,
3
+ isSecretReference,
4
+ parseYaml,
5
+ readLocalSecret,
6
+ resolveSecretStoreRoot,
7
+ toPortablePath
8
+ } from "./chunk-D7AYK7X5.js";
9
+
10
+ // ../../plugins/filesystem/src/helpers.ts
11
+ import { readdir } from "fs/promises";
12
+ import path from "path";
13
+ var YAML_EXTENSIONS = /* @__PURE__ */ new Set([".yml", ".yaml"]);
14
+ var FILESYSTEM_PLUGIN_ID = "@kitsy/cnos/plugins/filesystem";
15
+ async function existsDirectory(targetPath) {
16
+ try {
17
+ const stat = await readdir(targetPath);
18
+ void stat;
19
+ return true;
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+ async function collectYamlFiles(root) {
25
+ const entries = await readdir(root, { withFileTypes: true });
26
+ const results = [];
27
+ for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
28
+ const absolutePath = path.join(root, entry.name);
29
+ if (entry.isDirectory()) {
30
+ results.push(...await collectYamlFiles(absolutePath));
31
+ continue;
32
+ }
33
+ if (entry.isFile() && YAML_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) {
34
+ results.push(absolutePath);
35
+ }
36
+ }
37
+ return results;
38
+ }
39
+ async function collectFilesystemLayerFiles(manifestRoot, workspaceRoots, sourceRoot, activeLayers) {
40
+ const files = [];
41
+ const repoRoot = path.dirname(manifestRoot);
42
+ for (const workspaceRoot of workspaceRoots) {
43
+ const resolvedRoot = path.resolve(workspaceRoot.path, sourceRoot);
44
+ for (const layer of activeLayers) {
45
+ const layerRoot = path.join(resolvedRoot, layer);
46
+ if (!await existsDirectory(layerRoot)) {
47
+ continue;
48
+ }
49
+ for (const absolutePath of await collectYamlFiles(layerRoot)) {
50
+ const relativePath = path.relative(repoRoot, absolutePath);
51
+ files.push({
52
+ absolutePath,
53
+ relativePath: toPortablePath(relativePath.startsWith("..") ? absolutePath : relativePath),
54
+ workspaceId: workspaceRoot.workspaceId
55
+ });
56
+ }
57
+ }
58
+ }
59
+ return files;
60
+ }
61
+ function assertObjectDocument(value, filePath) {
62
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
63
+ throw new CnosManifestError("Filesystem loader expected a YAML object document", filePath);
64
+ }
65
+ return value;
66
+ }
67
+ function flattenConfigObject(value, options = {}, prefix = "") {
68
+ return Object.entries(value).reduce((accumulator, [key, nestedValue]) => {
69
+ const nextKey = prefix ? `${prefix}.${key}` : key;
70
+ if (nestedValue && typeof nestedValue === "object" && !Array.isArray(nestedValue) && !options.stopAtLeaf?.(nestedValue)) {
71
+ Object.assign(
72
+ accumulator,
73
+ flattenConfigObject(nestedValue, options, nextKey)
74
+ );
75
+ return accumulator;
76
+ }
77
+ accumulator[nextKey] = nestedValue;
78
+ return accumulator;
79
+ }, {});
80
+ }
81
+ function yamlObjectToEntries(document, filePath, namespace, sourceId, workspaceId = "default") {
82
+ const parsed = assertObjectDocument(parseYaml(document), filePath);
83
+ const flattened = flattenConfigObject(parsed, {
84
+ ...namespace === "secret" ? {
85
+ stopAtLeaf: isSecretReference
86
+ } : {}
87
+ });
88
+ return Object.entries(flattened).map(([key, value]) => ({
89
+ key: `${namespace}.${key}`,
90
+ value,
91
+ namespace,
92
+ sourceId,
93
+ pluginId: FILESYSTEM_PLUGIN_ID,
94
+ workspaceId,
95
+ origin: {
96
+ file: filePath
97
+ }
98
+ }));
99
+ }
100
+ async function resolveSecretValue(value, processEnv) {
101
+ if (!isSecretReference(value)) {
102
+ return value;
103
+ }
104
+ if (value.provider === "local") {
105
+ if (!processEnv?.CNOS_SECRET_PASSPHRASE) {
106
+ return value;
107
+ }
108
+ return readLocalSecret(
109
+ resolveSecretStoreRoot(processEnv),
110
+ value.ref,
111
+ processEnv?.CNOS_SECRET_PASSPHRASE
112
+ );
113
+ }
114
+ if (value.provider === "env") {
115
+ const resolved = processEnv?.[value.ref];
116
+ if (resolved === void 0) {
117
+ return value;
118
+ }
119
+ return resolved;
120
+ }
121
+ return value;
122
+ }
123
+ function toSecretReferenceMetadata(value) {
124
+ if (!isSecretReference(value)) {
125
+ return void 0;
126
+ }
127
+ return {
128
+ secretRef: value
129
+ };
130
+ }
131
+
132
+ // ../../plugins/filesystem/src/filesystemSecretsReader.ts
133
+ import { readFile } from "fs/promises";
134
+ function filesystemSecretsReader(filePath, document, workspaceId = "default") {
135
+ return yamlObjectToEntries(document, filePath, "secret", "filesystem-secrets", workspaceId);
136
+ }
137
+ function createFilesystemSecretsPlugin() {
138
+ return {
139
+ id: "filesystem-secrets",
140
+ kind: "loader",
141
+ async load(context) {
142
+ const sourceRoot = String(context.manifestConfig.root ?? "./");
143
+ const files = await collectFilesystemLayerFiles(
144
+ context.manifestRoot,
145
+ context.workspace.workspaceRoots,
146
+ sourceRoot,
147
+ context.profileActivation.secrets
148
+ );
149
+ const entries = [];
150
+ for (const file of files) {
151
+ const document = await readFile(file.absolutePath, "utf8");
152
+ const fileEntries = filesystemSecretsReader(file.relativePath, document, file.workspaceId);
153
+ for (const entry of fileEntries) {
154
+ const metadata = toSecretReferenceMetadata(entry.value);
155
+ const resolvedValue = await resolveSecretValue(entry.value, context.processEnv);
156
+ entries.push({
157
+ ...entry,
158
+ value: resolvedValue,
159
+ ...metadata ? { metadata } : {}
160
+ });
161
+ }
162
+ }
163
+ return entries;
164
+ }
165
+ };
166
+ }
167
+
168
+ // ../../plugins/filesystem/src/filesystemValuesReader.ts
169
+ import { readFile as readFile2 } from "fs/promises";
170
+ function filesystemValuesReader(filePath, document, workspaceId = "default") {
171
+ return yamlObjectToEntries(document, filePath, "value", "filesystem-values", workspaceId);
172
+ }
173
+ function createFilesystemValuesPlugin() {
174
+ return {
175
+ id: "filesystem-values",
176
+ kind: "loader",
177
+ async load(context) {
178
+ const sourceRoot = String(context.manifestConfig.root ?? "./");
179
+ const files = await collectFilesystemLayerFiles(
180
+ context.manifestRoot,
181
+ context.workspace.workspaceRoots,
182
+ sourceRoot,
183
+ context.profileActivation.values
184
+ );
185
+ const entries = [];
186
+ for (const file of files) {
187
+ const document = await readFile2(file.absolutePath, "utf8");
188
+ entries.push(...filesystemValuesReader(file.relativePath, document, file.workspaceId));
189
+ }
190
+ return entries;
191
+ }
192
+ };
193
+ }
194
+
195
+ export {
196
+ collectFilesystemLayerFiles,
197
+ yamlObjectToEntries,
198
+ filesystemSecretsReader,
199
+ createFilesystemSecretsPlugin,
200
+ filesystemValuesReader,
201
+ createFilesystemValuesPlugin
202
+ };
@@ -0,0 +1,109 @@
1
+ import {
2
+ envVarToLogicalKey,
3
+ resolveWorkspaceScopedPath,
4
+ toPortablePath
5
+ } from "./chunk-D7AYK7X5.js";
6
+
7
+ // ../../plugins/dotenv/src/index.ts
8
+ import { readFile } from "fs/promises";
9
+ import path from "path";
10
+ var DOTENV_PLUGIN_ID = "@kitsy/cnos/plugins/dotenv";
11
+ function parseDoubleQuoted(value) {
12
+ return value.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
13
+ }
14
+ function parseDotenv(document) {
15
+ const parsed = {};
16
+ for (const rawLine of document.split(/\r?\n/)) {
17
+ const line = rawLine.trim();
18
+ if (!line || line.startsWith("#")) {
19
+ continue;
20
+ }
21
+ const withoutExport = line.startsWith("export ") ? line.slice("export ".length).trim() : line;
22
+ const separatorIndex = withoutExport.indexOf("=");
23
+ if (separatorIndex <= 0) {
24
+ continue;
25
+ }
26
+ const envVar = withoutExport.slice(0, separatorIndex).trim();
27
+ let value = withoutExport.slice(separatorIndex + 1).trim();
28
+ if (!envVar) {
29
+ continue;
30
+ }
31
+ if (value.startsWith('"') && value.endsWith('"')) {
32
+ value = parseDoubleQuoted(value.slice(1, -1));
33
+ } else if (value.startsWith("'") && value.endsWith("'")) {
34
+ value = value.slice(1, -1);
35
+ } else {
36
+ value = value.replace(/\s+#.*$/, "").trim();
37
+ }
38
+ parsed[envVar] = value;
39
+ }
40
+ return parsed;
41
+ }
42
+ function dotenvEntriesFromObject(values, mapping = {}, originFile, workspaceId = "default") {
43
+ return Object.entries(values).flatMap(([envVar, value]) => {
44
+ const logicalKey = envVarToLogicalKey(envVar, mapping);
45
+ if (!logicalKey) {
46
+ return [];
47
+ }
48
+ return [
49
+ {
50
+ key: logicalKey,
51
+ value,
52
+ namespace: logicalKey.startsWith("secret.") ? "secret" : "value",
53
+ sourceId: "dotenv",
54
+ pluginId: DOTENV_PLUGIN_ID,
55
+ workspaceId,
56
+ origin: {
57
+ envVar,
58
+ ...originFile ? { file: originFile } : {}
59
+ }
60
+ }
61
+ ];
62
+ });
63
+ }
64
+ async function readIfPresent(filePath) {
65
+ try {
66
+ return await readFile(filePath, "utf8");
67
+ } catch {
68
+ return void 0;
69
+ }
70
+ }
71
+ function createDotenvPlugin() {
72
+ return {
73
+ id: "dotenv",
74
+ kind: "loader",
75
+ async load(context) {
76
+ const config = context.manifestConfig;
77
+ const rootTemplate = config.root ?? "./env";
78
+ const fileNames = context.profileActivation.envFiles;
79
+ const entries = [];
80
+ for (const workspaceRoot of context.workspace.workspaceRoots) {
81
+ const envRoot = resolveWorkspaceScopedPath(workspaceRoot.path, rootTemplate, {
82
+ workspace: workspaceRoot.workspaceId
83
+ });
84
+ for (const fileName of fileNames) {
85
+ const absolutePath = path.join(envRoot, fileName);
86
+ const document = await readIfPresent(absolutePath);
87
+ if (!document) {
88
+ continue;
89
+ }
90
+ entries.push(
91
+ ...dotenvEntriesFromObject(
92
+ parseDotenv(document),
93
+ config.envMapping,
94
+ toPortablePath(path.relative(path.dirname(context.manifestRoot), absolutePath)),
95
+ workspaceRoot.workspaceId
96
+ )
97
+ );
98
+ }
99
+ }
100
+ return entries;
101
+ }
102
+ };
103
+ }
104
+
105
+ export {
106
+ parseDotenv,
107
+ dotenvEntriesFromObject,
108
+ createDotenvPlugin
109
+ };
@@ -0,0 +1,83 @@
1
+ import {
2
+ joinConfigPath
3
+ } from "./chunk-D7AYK7X5.js";
4
+
5
+ // ../../plugins/cli-args/src/index.ts
6
+ var CLI_ARGS_PLUGIN_ID = "@kitsy/cnos/plugins/cli-args";
7
+ function isNamespaceName(value) {
8
+ return value === "value" || value === "secret";
9
+ }
10
+ function parseCliArgs(args) {
11
+ const parsed = [];
12
+ for (let index = 0; index < args.length; index += 1) {
13
+ const arg = args[index];
14
+ if (!arg?.startsWith("--")) {
15
+ continue;
16
+ }
17
+ if (arg === "--profile") {
18
+ index += 1;
19
+ continue;
20
+ }
21
+ if (arg.startsWith("--profile=")) {
22
+ continue;
23
+ }
24
+ const body = arg.slice(2);
25
+ const separatorIndex = body.indexOf("=");
26
+ if (separatorIndex >= 0) {
27
+ parsed.push({
28
+ key: body.slice(0, separatorIndex),
29
+ value: body.slice(separatorIndex + 1),
30
+ raw: arg
31
+ });
32
+ continue;
33
+ }
34
+ const nextValue = args[index + 1];
35
+ if (nextValue && !nextValue.startsWith("--")) {
36
+ parsed.push({
37
+ key: body,
38
+ value: nextValue,
39
+ raw: `${arg} ${nextValue}`
40
+ });
41
+ index += 1;
42
+ }
43
+ }
44
+ return parsed;
45
+ }
46
+ function cliArgEntriesFromArgs(args, workspaceId = "default") {
47
+ return parseCliArgs(args).flatMap(({ key, value, raw }) => {
48
+ const [candidateNamespace = "", ...pathSegments] = key.split(".");
49
+ if (!isNamespaceName(candidateNamespace) || pathSegments.length === 0) {
50
+ return [];
51
+ }
52
+ const namespace = candidateNamespace;
53
+ const logicalKey = `${namespace}.${joinConfigPath(pathSegments.join("."))}`;
54
+ return [
55
+ {
56
+ key: logicalKey,
57
+ value,
58
+ namespace,
59
+ sourceId: "cli-args",
60
+ pluginId: CLI_ARGS_PLUGIN_ID,
61
+ workspaceId,
62
+ origin: {
63
+ cliArg: raw
64
+ }
65
+ }
66
+ ];
67
+ });
68
+ }
69
+ function createCliArgsPlugin() {
70
+ return {
71
+ id: "cli-args",
72
+ kind: "loader",
73
+ async load(context) {
74
+ return cliArgEntriesFromArgs(context.cliArgs ?? [], context.workspace.workspaceId);
75
+ }
76
+ };
77
+ }
78
+
79
+ export {
80
+ parseCliArgs,
81
+ cliArgEntriesFromArgs,
82
+ createCliArgsPlugin
83
+ };
@@ -0,0 +1,35 @@
1
+ import {
2
+ toEnv,
3
+ toPublicEnv
4
+ } from "./chunk-D7AYK7X5.js";
5
+
6
+ // ../../plugins/env-export/src/index.ts
7
+ function createEnvExportPlugin() {
8
+ return {
9
+ id: "@kitsy/cnos/plugins/env-export",
10
+ kind: "exporter",
11
+ async export(graph, context) {
12
+ return {
13
+ pluginId: "@kitsy/cnos/plugins/env-export",
14
+ value: toEnv(graph, context.manifest)
15
+ };
16
+ }
17
+ };
18
+ }
19
+ function createPublicEnvExportPlugin() {
20
+ return {
21
+ id: "@kitsy/cnos/plugins/public-env-export",
22
+ kind: "exporter",
23
+ async export(graph, context) {
24
+ return {
25
+ pluginId: "@kitsy/cnos/plugins/public-env-export",
26
+ value: toPublicEnv(graph, context.manifest)
27
+ };
28
+ }
29
+ };
30
+ }
31
+
32
+ export {
33
+ createEnvExportPlugin,
34
+ createPublicEnvExportPlugin
35
+ };
@@ -0,0 +1,8 @@
1
+ import { N as NormalizedManifest, g as LogicalKey } from './plugin-BVNEHj19.cjs';
2
+
3
+ interface EnvMappingConfig {
4
+ convention?: NormalizedManifest['envMapping']['convention'];
5
+ explicit?: Record<string, LogicalKey>;
6
+ }
7
+
8
+ export type { EnvMappingConfig as E };
@@ -0,0 +1,8 @@
1
+ import { N as NormalizedManifest, g as LogicalKey } from './plugin-BVNEHj19.js';
2
+
3
+ interface EnvMappingConfig {
4
+ convention?: NormalizedManifest['envMapping']['convention'];
5
+ explicit?: Record<string, LogicalKey>;
6
+ }
7
+
8
+ export type { EnvMappingConfig as E };