@classytic/arc 1.1.0 → 2.1.2
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/README.md +247 -794
- package/bin/arc.js +91 -52
- package/dist/EventTransport-BD2U0BTc.d.mts +100 -0
- package/dist/EventTransport-BD2U0BTc.d.mts.map +1 -0
- package/dist/HookSystem-BsGV-j2l.mjs +405 -0
- package/dist/HookSystem-BsGV-j2l.mjs.map +1 -0
- package/dist/ResourceRegistry-DsN4KJjV.mjs +250 -0
- package/dist/ResourceRegistry-DsN4KJjV.mjs.map +1 -0
- package/dist/adapters/index.d.mts +5 -0
- package/dist/adapters/index.mjs +3 -0
- package/dist/audit/index.d.mts +82 -0
- package/dist/audit/index.d.mts.map +1 -0
- package/dist/audit/index.mjs +276 -0
- package/dist/audit/index.mjs.map +1 -0
- package/dist/audit/mongodb.d.mts +5 -0
- package/dist/audit/mongodb.mjs +3 -0
- package/dist/audited-C3T5DTUx.mjs +141 -0
- package/dist/audited-C3T5DTUx.mjs.map +1 -0
- package/dist/auth/index.d.mts +189 -0
- package/dist/auth/index.d.mts.map +1 -0
- package/dist/auth/index.mjs +1102 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/auth/redis-session.d.mts +44 -0
- package/dist/auth/redis-session.d.mts.map +1 -0
- package/dist/auth/redis-session.mjs +76 -0
- package/dist/auth/redis-session.mjs.map +1 -0
- package/dist/betterAuthOpenApi-BrHKeSAx.mjs +250 -0
- package/dist/betterAuthOpenApi-BrHKeSAx.mjs.map +1 -0
- package/dist/cache/index.d.mts +146 -0
- package/dist/cache/index.d.mts.map +1 -0
- package/dist/cache/index.mjs +92 -0
- package/dist/cache/index.mjs.map +1 -0
- package/dist/caching-Bl28lYsR.mjs +94 -0
- package/dist/caching-Bl28lYsR.mjs.map +1 -0
- package/dist/chunk-C7Uep-_p.mjs +20 -0
- package/dist/circuitBreaker-DeY4FCjs.mjs +1097 -0
- package/dist/circuitBreaker-DeY4FCjs.mjs.map +1 -0
- package/dist/cli/commands/describe.d.mts +19 -0
- package/dist/cli/commands/describe.d.mts.map +1 -0
- package/dist/cli/commands/describe.mjs +239 -0
- package/dist/cli/commands/describe.mjs.map +1 -0
- package/dist/cli/commands/docs.d.mts +14 -0
- package/dist/cli/commands/docs.d.mts.map +1 -0
- package/dist/cli/commands/docs.mjs +53 -0
- package/dist/cli/commands/docs.mjs.map +1 -0
- package/dist/cli/commands/{generate.d.ts → generate.d.mts} +3 -1
- package/dist/cli/commands/generate.d.mts.map +1 -0
- package/dist/cli/commands/generate.mjs +358 -0
- package/dist/cli/commands/generate.mjs.map +1 -0
- package/dist/cli/commands/{init.d.ts → init.d.mts} +12 -8
- package/dist/cli/commands/init.d.mts.map +1 -0
- package/dist/cli/commands/{init.js → init.mjs} +807 -616
- package/dist/cli/commands/init.mjs.map +1 -0
- package/dist/cli/commands/introspect.d.mts +11 -0
- package/dist/cli/commands/introspect.d.mts.map +1 -0
- package/dist/cli/commands/introspect.mjs +76 -0
- package/dist/cli/commands/introspect.mjs.map +1 -0
- package/dist/cli/index.d.mts +17 -0
- package/dist/cli/index.d.mts.map +1 -0
- package/dist/cli/index.mjs +157 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/constants-DdXFXQtN.mjs +85 -0
- package/dist/constants-DdXFXQtN.mjs.map +1 -0
- package/dist/core/index.d.mts +5 -0
- package/dist/core/index.mjs +4 -0
- package/dist/createApp-CUgNqegw.mjs +560 -0
- package/dist/createApp-CUgNqegw.mjs.map +1 -0
- package/dist/defineResource-k0_BDn8v.mjs +2197 -0
- package/dist/defineResource-k0_BDn8v.mjs.map +1 -0
- package/dist/discovery/index.d.mts +47 -0
- package/dist/discovery/index.d.mts.map +1 -0
- package/dist/discovery/index.mjs +110 -0
- package/dist/discovery/index.mjs.map +1 -0
- package/dist/docs/index.d.mts +163 -0
- package/dist/docs/index.d.mts.map +1 -0
- package/dist/docs/index.mjs +73 -0
- package/dist/docs/index.mjs.map +1 -0
- package/dist/elevation-BRy3yFWT.mjs +113 -0
- package/dist/elevation-BRy3yFWT.mjs.map +1 -0
- package/dist/elevation-B_2dRLVP.d.mts +88 -0
- package/dist/elevation-B_2dRLVP.d.mts.map +1 -0
- package/dist/errorHandler-BbcgBmIH.d.mts +73 -0
- package/dist/errorHandler-BbcgBmIH.d.mts.map +1 -0
- package/dist/errorHandler-C1okiriz.mjs +109 -0
- package/dist/errorHandler-C1okiriz.mjs.map +1 -0
- package/dist/errors-B9bZok84.mjs +212 -0
- package/dist/errors-B9bZok84.mjs.map +1 -0
- package/dist/errors-ChKiFz62.d.mts +125 -0
- package/dist/errors-ChKiFz62.d.mts.map +1 -0
- package/dist/eventPlugin-CTrLH3mt.d.mts +125 -0
- package/dist/eventPlugin-CTrLH3mt.d.mts.map +1 -0
- package/dist/eventPlugin-DGR_B2on.mjs +230 -0
- package/dist/eventPlugin-DGR_B2on.mjs.map +1 -0
- package/dist/events/index.d.mts +54 -0
- package/dist/events/index.d.mts.map +1 -0
- package/dist/events/index.mjs +52 -0
- package/dist/events/index.mjs.map +1 -0
- package/dist/events/transports/redis-stream-entry.d.mts +2 -0
- package/dist/events/transports/redis-stream-entry.mjs +178 -0
- package/dist/events/transports/redis-stream-entry.mjs.map +1 -0
- package/dist/events/transports/redis.d.mts +77 -0
- package/dist/events/transports/redis.d.mts.map +1 -0
- package/dist/events/transports/redis.mjs +125 -0
- package/dist/events/transports/redis.mjs.map +1 -0
- package/dist/externalPaths-DlINfKbP.d.mts +51 -0
- package/dist/externalPaths-DlINfKbP.d.mts.map +1 -0
- package/dist/factory/index.d.mts +64 -0
- package/dist/factory/index.d.mts.map +1 -0
- package/dist/factory/index.mjs +3 -0
- package/dist/fastifyAdapter-BkrGrlFi.d.mts +217 -0
- package/dist/fastifyAdapter-BkrGrlFi.d.mts.map +1 -0
- package/dist/fields-DyaDVX4J.d.mts +110 -0
- package/dist/fields-DyaDVX4J.d.mts.map +1 -0
- package/dist/fields-iagOozy0.mjs +115 -0
- package/dist/fields-iagOozy0.mjs.map +1 -0
- package/dist/hooks/index.d.mts +4 -0
- package/dist/hooks/index.mjs +3 -0
- package/dist/idempotency/index.d.mts +97 -0
- package/dist/idempotency/index.d.mts.map +1 -0
- package/dist/idempotency/index.mjs +320 -0
- package/dist/idempotency/index.mjs.map +1 -0
- package/dist/idempotency/mongodb.d.mts +2 -0
- package/dist/idempotency/mongodb.mjs +115 -0
- package/dist/idempotency/mongodb.mjs.map +1 -0
- package/dist/idempotency/redis.d.mts +2 -0
- package/dist/idempotency/redis.mjs +104 -0
- package/dist/idempotency/redis.mjs.map +1 -0
- package/dist/index.d.mts +261 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +105 -0
- package/dist/index.mjs.map +1 -0
- package/dist/integrations/event-gateway.d.mts +47 -0
- package/dist/integrations/event-gateway.d.mts.map +1 -0
- package/dist/integrations/event-gateway.mjs +44 -0
- package/dist/integrations/event-gateway.mjs.map +1 -0
- package/dist/integrations/index.d.mts +5 -0
- package/dist/integrations/index.mjs +1 -0
- package/dist/integrations/jobs.d.mts +104 -0
- package/dist/integrations/jobs.d.mts.map +1 -0
- package/dist/integrations/jobs.mjs +124 -0
- package/dist/integrations/jobs.mjs.map +1 -0
- package/dist/integrations/streamline.d.mts +61 -0
- package/dist/integrations/streamline.d.mts.map +1 -0
- package/dist/integrations/streamline.mjs +126 -0
- package/dist/integrations/streamline.mjs.map +1 -0
- package/dist/integrations/websocket.d.mts +83 -0
- package/dist/integrations/websocket.d.mts.map +1 -0
- package/dist/integrations/websocket.mjs +289 -0
- package/dist/integrations/websocket.mjs.map +1 -0
- package/dist/interface-B01JvPVc.d.mts +78 -0
- package/dist/interface-B01JvPVc.d.mts.map +1 -0
- package/dist/interface-CZe8IkMf.d.mts +55 -0
- package/dist/interface-CZe8IkMf.d.mts.map +1 -0
- package/dist/interface-Ch8HU9uM.d.mts +1098 -0
- package/dist/interface-Ch8HU9uM.d.mts.map +1 -0
- package/dist/introspectionPlugin-rFdO8ZUa.mjs +54 -0
- package/dist/introspectionPlugin-rFdO8ZUa.mjs.map +1 -0
- package/dist/keys-BqNejWup.mjs +43 -0
- package/dist/keys-BqNejWup.mjs.map +1 -0
- package/dist/logger-Df2O2WsW.mjs +79 -0
- package/dist/logger-Df2O2WsW.mjs.map +1 -0
- package/dist/memory-cQgelFOj.mjs +144 -0
- package/dist/memory-cQgelFOj.mjs.map +1 -0
- package/dist/migrations/index.d.mts +157 -0
- package/dist/migrations/index.d.mts.map +1 -0
- package/dist/migrations/index.mjs +261 -0
- package/dist/migrations/index.mjs.map +1 -0
- package/dist/mongodb-BfJVlUJH.mjs +94 -0
- package/dist/mongodb-BfJVlUJH.mjs.map +1 -0
- package/dist/mongodb-CGzRbfAK.d.mts +119 -0
- package/dist/mongodb-CGzRbfAK.d.mts.map +1 -0
- package/dist/mongodb-JN-9JA7K.d.mts +72 -0
- package/dist/mongodb-JN-9JA7K.d.mts.map +1 -0
- package/dist/openapi-G3Cw7XuM.mjs +524 -0
- package/dist/openapi-G3Cw7XuM.mjs.map +1 -0
- package/dist/org/index.d.mts +69 -0
- package/dist/org/index.d.mts.map +1 -0
- package/dist/org/index.mjs +514 -0
- package/dist/org/index.mjs.map +1 -0
- package/dist/org/types.d.mts +83 -0
- package/dist/org/types.d.mts.map +1 -0
- package/dist/org/types.mjs +1 -0
- package/dist/permissions/index.d.mts +279 -0
- package/dist/permissions/index.d.mts.map +1 -0
- package/dist/permissions/index.mjs +579 -0
- package/dist/permissions/index.mjs.map +1 -0
- package/dist/plugins/index.d.mts +173 -0
- package/dist/plugins/index.d.mts.map +1 -0
- package/dist/plugins/index.mjs +523 -0
- package/dist/plugins/index.mjs.map +1 -0
- package/dist/plugins/response-cache.d.mts +88 -0
- package/dist/plugins/response-cache.d.mts.map +1 -0
- package/dist/plugins/response-cache.mjs +284 -0
- package/dist/plugins/response-cache.mjs.map +1 -0
- package/dist/plugins/tracing-entry.d.mts +2 -0
- package/dist/plugins/tracing-entry.mjs +186 -0
- package/dist/plugins/tracing-entry.mjs.map +1 -0
- package/dist/pluralize-CEweyOEm.mjs +87 -0
- package/dist/pluralize-CEweyOEm.mjs.map +1 -0
- package/dist/policies/{index.d.ts → index.d.mts} +204 -169
- package/dist/policies/index.d.mts.map +1 -0
- package/dist/policies/index.mjs +322 -0
- package/dist/policies/index.mjs.map +1 -0
- package/dist/presets/{index.d.ts → index.d.mts} +63 -131
- package/dist/presets/index.d.mts.map +1 -0
- package/dist/presets/index.mjs +144 -0
- package/dist/presets/index.mjs.map +1 -0
- package/dist/presets/multiTenant.d.mts +25 -0
- package/dist/presets/multiTenant.d.mts.map +1 -0
- package/dist/presets/multiTenant.mjs +114 -0
- package/dist/presets/multiTenant.mjs.map +1 -0
- package/dist/presets-BITljm96.mjs +120 -0
- package/dist/presets-BITljm96.mjs.map +1 -0
- package/dist/presets-DzSMwlKj.d.mts +58 -0
- package/dist/presets-DzSMwlKj.d.mts.map +1 -0
- package/dist/prisma-DJbMt3yf.mjs +628 -0
- package/dist/prisma-DJbMt3yf.mjs.map +1 -0
- package/dist/prisma-Dg9GoVdj.d.mts +275 -0
- package/dist/prisma-Dg9GoVdj.d.mts.map +1 -0
- package/dist/queryCachePlugin-7THaI5mt.d.mts +72 -0
- package/dist/queryCachePlugin-7THaI5mt.d.mts.map +1 -0
- package/dist/queryCachePlugin-DMBnp2Q0.mjs +139 -0
- package/dist/queryCachePlugin-DMBnp2Q0.mjs.map +1 -0
- package/dist/redis-D-JAeLtm.d.mts +50 -0
- package/dist/redis-D-JAeLtm.d.mts.map +1 -0
- package/dist/redis-stream-Bdh_vUU8.d.mts +104 -0
- package/dist/redis-stream-Bdh_vUU8.d.mts.map +1 -0
- package/dist/registry/index.d.mts +12 -0
- package/dist/registry/index.d.mts.map +1 -0
- package/dist/registry/index.mjs +4 -0
- package/dist/requestContext-QQD6ROJc.mjs +56 -0
- package/dist/requestContext-QQD6ROJc.mjs.map +1 -0
- package/dist/schemaConverter-BwrmWroW.mjs +99 -0
- package/dist/schemaConverter-BwrmWroW.mjs.map +1 -0
- package/dist/schemas/index.d.mts +64 -0
- package/dist/schemas/index.d.mts.map +1 -0
- package/dist/schemas/index.mjs +83 -0
- package/dist/schemas/index.mjs.map +1 -0
- package/dist/scope/index.d.mts +22 -0
- package/dist/scope/index.d.mts.map +1 -0
- package/dist/scope/index.mjs +66 -0
- package/dist/scope/index.mjs.map +1 -0
- package/dist/sessionManager-jPKLbHE0.d.mts +187 -0
- package/dist/sessionManager-jPKLbHE0.d.mts.map +1 -0
- package/dist/sse-B3c3_yZp.mjs +124 -0
- package/dist/sse-B3c3_yZp.mjs.map +1 -0
- package/dist/testing/index.d.mts +908 -0
- package/dist/testing/index.d.mts.map +1 -0
- package/dist/testing/index.mjs +1977 -0
- package/dist/testing/index.mjs.map +1 -0
- package/dist/tracing-Cc7vVQPp.d.mts +71 -0
- package/dist/tracing-Cc7vVQPp.d.mts.map +1 -0
- package/dist/typeGuards-DhMNLuvU.mjs +10 -0
- package/dist/typeGuards-DhMNLuvU.mjs.map +1 -0
- package/dist/types/index.d.mts +947 -0
- package/dist/types/index.d.mts.map +1 -0
- package/dist/types/index.mjs +15 -0
- package/dist/types/index.mjs.map +1 -0
- package/dist/types-Beqn1Un7.mjs +39 -0
- package/dist/types-Beqn1Un7.mjs.map +1 -0
- package/dist/types-CIgB7UUl.d.mts +446 -0
- package/dist/types-CIgB7UUl.d.mts.map +1 -0
- package/dist/types-aYB4V7uN.d.mts +87 -0
- package/dist/types-aYB4V7uN.d.mts.map +1 -0
- package/dist/utils/index.d.mts +748 -0
- package/dist/utils/index.d.mts.map +1 -0
- package/dist/utils/index.mjs +6 -0
- package/package.json +194 -68
- package/dist/BaseController-DVAiHxEQ.d.ts +0 -233
- package/dist/adapters/index.d.ts +0 -237
- package/dist/adapters/index.js +0 -668
- package/dist/arcCorePlugin-CsShQdyP.d.ts +0 -273
- package/dist/audit/index.d.ts +0 -195
- package/dist/audit/index.js +0 -319
- package/dist/auth/index.d.ts +0 -47
- package/dist/auth/index.js +0 -174
- package/dist/cli/commands/docs.d.ts +0 -11
- package/dist/cli/commands/docs.js +0 -474
- package/dist/cli/commands/generate.js +0 -334
- package/dist/cli/commands/introspect.d.ts +0 -8
- package/dist/cli/commands/introspect.js +0 -338
- package/dist/cli/index.d.ts +0 -4
- package/dist/cli/index.js +0 -3269
- package/dist/core/index.d.ts +0 -220
- package/dist/core/index.js +0 -2786
- package/dist/createApp-Ce9wl8W9.d.ts +0 -77
- package/dist/docs/index.d.ts +0 -166
- package/dist/docs/index.js +0 -658
- package/dist/errors-8WIxGS_6.d.ts +0 -122
- package/dist/events/index.d.ts +0 -117
- package/dist/events/index.js +0 -89
- package/dist/factory/index.d.ts +0 -38
- package/dist/factory/index.js +0 -1652
- package/dist/hooks/index.d.ts +0 -4
- package/dist/hooks/index.js +0 -199
- package/dist/idempotency/index.d.ts +0 -323
- package/dist/idempotency/index.js +0 -500
- package/dist/index-B4t03KQ0.d.ts +0 -1366
- package/dist/index.d.ts +0 -135
- package/dist/index.js +0 -4756
- package/dist/migrations/index.d.ts +0 -185
- package/dist/migrations/index.js +0 -274
- package/dist/org/index.d.ts +0 -129
- package/dist/org/index.js +0 -220
- package/dist/permissions/index.d.ts +0 -144
- package/dist/permissions/index.js +0 -103
- package/dist/plugins/index.d.ts +0 -46
- package/dist/plugins/index.js +0 -1069
- package/dist/policies/index.js +0 -196
- package/dist/presets/index.js +0 -384
- package/dist/presets/multiTenant.d.ts +0 -39
- package/dist/presets/multiTenant.js +0 -112
- package/dist/registry/index.d.ts +0 -16
- package/dist/registry/index.js +0 -253
- package/dist/testing/index.d.ts +0 -618
- package/dist/testing/index.js +0 -48020
- package/dist/types/index.d.ts +0 -4
- package/dist/types/index.js +0 -8
- package/dist/types-B99TBmFV.d.ts +0 -76
- package/dist/types-BvckRbs2.d.ts +0 -143
- package/dist/utils/index.d.ts +0 -679
- package/dist/utils/index.js +0 -931
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { t as pluralize } from "../../pluralize-CEweyOEm.mjs";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
//#region src/cli/commands/generate.ts
|
|
6
|
+
/**
|
|
7
|
+
* Arc CLI - Generate Command
|
|
8
|
+
*
|
|
9
|
+
* Scaffolds resources with consistent naming:
|
|
10
|
+
* - src/resources/product/product.model.ts
|
|
11
|
+
* - src/resources/product/product.repository.ts
|
|
12
|
+
* - src/resources/product/product.resource.ts
|
|
13
|
+
* - src/resources/product/product.controller.ts
|
|
14
|
+
* - src/resources/product/product.schemas.ts
|
|
15
|
+
*/
|
|
16
|
+
function readProjectConfig() {
|
|
17
|
+
try {
|
|
18
|
+
const rcPath = join(process.cwd(), ".arcrc");
|
|
19
|
+
return JSON.parse(readFileSync(rcPath, "utf-8"));
|
|
20
|
+
} catch {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function isTypeScriptProject() {
|
|
25
|
+
return existsSync(join(process.cwd(), "tsconfig.json"));
|
|
26
|
+
}
|
|
27
|
+
function getTemplates(ts, config = {}) {
|
|
28
|
+
const isMultiTenant = config.tenant === "multi";
|
|
29
|
+
return {
|
|
30
|
+
model: (name) => `/**
|
|
31
|
+
* ${name} Model
|
|
32
|
+
* Generated by Arc CLI
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
import mongoose${ts ? ", { type HydratedDocument }" : ""} from 'mongoose';
|
|
36
|
+
|
|
37
|
+
const { Schema } = mongoose;
|
|
38
|
+
${ts ? `
|
|
39
|
+
export interface I${name} {
|
|
40
|
+
name: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
isActive: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type ${name}Document = HydratedDocument<I${name}>;
|
|
46
|
+
` : ""}
|
|
47
|
+
const ${name.toLowerCase()}Schema = new Schema${ts ? `<I${name}>` : ""}(
|
|
48
|
+
{
|
|
49
|
+
name: { type: String, required: true, trim: true },
|
|
50
|
+
description: { type: String, trim: true },
|
|
51
|
+
isActive: { type: Boolean, default: true },
|
|
52
|
+
},
|
|
53
|
+
{ timestamps: true }
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// Indexes
|
|
57
|
+
${name.toLowerCase()}Schema.index({ name: 1 });
|
|
58
|
+
${name.toLowerCase()}Schema.index({ isActive: 1 });
|
|
59
|
+
|
|
60
|
+
const ${name} = mongoose.models.${name} || mongoose.model('${name}', ${name.toLowerCase()}Schema);
|
|
61
|
+
export default ${name};
|
|
62
|
+
`,
|
|
63
|
+
repository: (name) => `/**
|
|
64
|
+
* ${name} Repository
|
|
65
|
+
* Generated by Arc CLI
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
import {
|
|
69
|
+
Repository,
|
|
70
|
+
methodRegistryPlugin,
|
|
71
|
+
softDeletePlugin,
|
|
72
|
+
mongoOperationsPlugin,
|
|
73
|
+
} from '@classytic/mongokit';
|
|
74
|
+
import ${name} from './${name.toLowerCase()}.model.js';
|
|
75
|
+
|
|
76
|
+
class ${name}Repository extends Repository {
|
|
77
|
+
constructor() {
|
|
78
|
+
super(${name}, [
|
|
79
|
+
methodRegistryPlugin(),
|
|
80
|
+
softDeletePlugin(),
|
|
81
|
+
mongoOperationsPlugin(),
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Find all active records
|
|
87
|
+
*/
|
|
88
|
+
async findActive() {
|
|
89
|
+
return this.Model.find({ isActive: true, deletedAt: null }).lean();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const ${name.toLowerCase()}Repository = new ${name}Repository();
|
|
94
|
+
export default ${name.toLowerCase()}Repository;
|
|
95
|
+
export { ${name}Repository };
|
|
96
|
+
`,
|
|
97
|
+
controller: (name) => `/**
|
|
98
|
+
* ${name} Controller
|
|
99
|
+
* Generated by Arc CLI
|
|
100
|
+
*
|
|
101
|
+
* Note: defineResource() auto-creates a controller from the adapter.
|
|
102
|
+
* Only create a custom controller when you need custom methods.
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
import { BaseController } from '@classytic/arc';
|
|
106
|
+
import ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';
|
|
107
|
+
|
|
108
|
+
class ${name}Controller extends BaseController {
|
|
109
|
+
constructor() {
|
|
110
|
+
super(${name.toLowerCase()}Repository, {
|
|
111
|
+
resourceName: '${name.toLowerCase()}',
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Add custom controller methods here
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const ${name.toLowerCase()}Controller = new ${name}Controller();
|
|
119
|
+
export default ${name.toLowerCase()}Controller;
|
|
120
|
+
`,
|
|
121
|
+
schemas: (name) => `/**
|
|
122
|
+
* ${name} Schemas
|
|
123
|
+
* Generated by Arc CLI
|
|
124
|
+
*/
|
|
125
|
+
|
|
126
|
+
import ${name} from './${name.toLowerCase()}.model.js';
|
|
127
|
+
import { buildCrudSchemasFromModel } from '@classytic/mongokit/utils';
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* CRUD Schemas with Field Rules
|
|
131
|
+
*/
|
|
132
|
+
const crudSchemas = buildCrudSchemasFromModel(${name}, {
|
|
133
|
+
strictAdditionalProperties: true,
|
|
134
|
+
fieldRules: {
|
|
135
|
+
// Mark fields as system-managed (excluded from create/update)
|
|
136
|
+
// deletedAt: { systemManaged: true },
|
|
137
|
+
},
|
|
138
|
+
query: {
|
|
139
|
+
filterableFields: {
|
|
140
|
+
isActive: 'boolean',
|
|
141
|
+
createdAt: 'date',
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
export default crudSchemas;
|
|
147
|
+
`,
|
|
148
|
+
resource: (name) => {
|
|
149
|
+
const useMongoKit = config.adapter === "mongokit" || !config.adapter;
|
|
150
|
+
const queryParserImport = useMongoKit ? `\nimport { QueryParser } from '@classytic/mongokit';\n\nconst queryParser = new QueryParser();\n` : "";
|
|
151
|
+
const queryParserConfig = useMongoKit ? `\n queryParser,` : "";
|
|
152
|
+
return isMultiTenant ? `/**
|
|
153
|
+
* ${name} Resource
|
|
154
|
+
* Generated by Arc CLI
|
|
155
|
+
*/
|
|
156
|
+
|
|
157
|
+
import { defineResource, createMongooseAdapter } from '@classytic/arc';
|
|
158
|
+
import { requireOrgMembership, requireOrgRole } from '@classytic/arc/permissions';
|
|
159
|
+
import ${name}${ts ? `, { type I${name} }` : ""} from './${name.toLowerCase()}.model.js';
|
|
160
|
+
import ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';${queryParserImport}
|
|
161
|
+
|
|
162
|
+
const ${name.toLowerCase()}Resource = defineResource${ts ? `<I${name}>` : ""}({
|
|
163
|
+
name: '${name.toLowerCase()}',
|
|
164
|
+
adapter: createMongooseAdapter(${name}, ${name.toLowerCase()}Repository),${queryParserConfig}
|
|
165
|
+
presets: ['softDelete'],
|
|
166
|
+
permissions: {
|
|
167
|
+
list: requireOrgMembership(),
|
|
168
|
+
get: requireOrgMembership(),
|
|
169
|
+
create: requireOrgRole('admin'),
|
|
170
|
+
update: requireOrgRole('admin'),
|
|
171
|
+
delete: requireOrgRole('admin'),
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
export default ${name.toLowerCase()}Resource;
|
|
176
|
+
` : `/**
|
|
177
|
+
* ${name} Resource
|
|
178
|
+
* Generated by Arc CLI
|
|
179
|
+
*/
|
|
180
|
+
|
|
181
|
+
import { defineResource, createMongooseAdapter } from '@classytic/arc';
|
|
182
|
+
import { requireAuth, requireRoles } from '@classytic/arc/permissions';
|
|
183
|
+
import ${name}${ts ? `, { type I${name} }` : ""} from './${name.toLowerCase()}.model.js';
|
|
184
|
+
import ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';${queryParserImport}
|
|
185
|
+
|
|
186
|
+
const ${name.toLowerCase()}Resource = defineResource${ts ? `<I${name}>` : ""}({
|
|
187
|
+
name: '${name.toLowerCase()}',
|
|
188
|
+
adapter: createMongooseAdapter(${name}, ${name.toLowerCase()}Repository),${queryParserConfig}
|
|
189
|
+
presets: ['softDelete'],
|
|
190
|
+
permissions: {
|
|
191
|
+
list: requireAuth(),
|
|
192
|
+
get: requireAuth(),
|
|
193
|
+
create: requireRoles(['admin']),
|
|
194
|
+
update: requireRoles(['admin']),
|
|
195
|
+
delete: requireRoles(['admin']),
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
export default ${name.toLowerCase()}Resource;
|
|
200
|
+
`;
|
|
201
|
+
},
|
|
202
|
+
test: (name) => `/**
|
|
203
|
+
* ${name} Tests
|
|
204
|
+
* Generated by Arc CLI
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
208
|
+
import mongoose from 'mongoose';
|
|
209
|
+
import { createMinimalTestApp } from '@classytic/arc/testing';
|
|
210
|
+
${ts ? "import type { FastifyInstance } from 'fastify';\n" : ""}import ${name.toLowerCase()}Resource from '../src/resources/${name.toLowerCase()}/${name.toLowerCase()}.resource.js';
|
|
211
|
+
|
|
212
|
+
describe('${name} Resource', () => {
|
|
213
|
+
let app${ts ? ": FastifyInstance" : ""};
|
|
214
|
+
|
|
215
|
+
beforeAll(async () => {
|
|
216
|
+
const testDbUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/arc-app-test';
|
|
217
|
+
await mongoose.connect(testDbUri);
|
|
218
|
+
|
|
219
|
+
app = createMinimalTestApp();
|
|
220
|
+
await app.register(${name.toLowerCase()}Resource.toPlugin());
|
|
221
|
+
await app.ready();
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
afterAll(async () => {
|
|
225
|
+
await app.close();
|
|
226
|
+
await mongoose.connection.close();
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
describe('GET /${pluralize(name.toLowerCase())}', () => {
|
|
230
|
+
it('should return a list', async () => {
|
|
231
|
+
const response = await app.inject({
|
|
232
|
+
method: 'GET',
|
|
233
|
+
url: '/${pluralize(name.toLowerCase())}',
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
expect(response.statusCode).toBe(200);
|
|
237
|
+
const body = JSON.parse(response.body);
|
|
238
|
+
expect(body).toHaveProperty('docs');
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
`
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Generate command handler
|
|
247
|
+
*/
|
|
248
|
+
async function generate(type, args) {
|
|
249
|
+
if (!type) throw new Error("Missing type argument\nUsage: arc generate <resource|controller|model|repository|schemas> <name>");
|
|
250
|
+
const [name] = args;
|
|
251
|
+
if (!name) throw new Error("Missing name argument\nUsage: arc generate <type> <name>\nExample: arc generate resource product");
|
|
252
|
+
const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);
|
|
253
|
+
const lowerName = name.toLowerCase();
|
|
254
|
+
const projectConfig = readProjectConfig();
|
|
255
|
+
const ts = projectConfig.typescript ?? isTypeScriptProject();
|
|
256
|
+
const ext = ts ? "ts" : "js";
|
|
257
|
+
const templates = getTemplates(ts, projectConfig);
|
|
258
|
+
const resourcePath = join(process.cwd(), "src", "resources", lowerName);
|
|
259
|
+
switch (type) {
|
|
260
|
+
case "resource":
|
|
261
|
+
case "r":
|
|
262
|
+
await generateResource(capitalizedName, lowerName, resourcePath, templates, ext);
|
|
263
|
+
break;
|
|
264
|
+
case "controller":
|
|
265
|
+
case "c":
|
|
266
|
+
await generateFile(capitalizedName, lowerName, resourcePath, "controller", templates.controller, ext);
|
|
267
|
+
break;
|
|
268
|
+
case "model":
|
|
269
|
+
case "m":
|
|
270
|
+
await generateFile(capitalizedName, lowerName, resourcePath, "model", templates.model, ext);
|
|
271
|
+
break;
|
|
272
|
+
case "repository":
|
|
273
|
+
case "repo":
|
|
274
|
+
await generateFile(capitalizedName, lowerName, resourcePath, "repository", templates.repository, ext);
|
|
275
|
+
break;
|
|
276
|
+
case "schemas":
|
|
277
|
+
case "s":
|
|
278
|
+
await generateFile(capitalizedName, lowerName, resourcePath, "schemas", templates.schemas, ext);
|
|
279
|
+
break;
|
|
280
|
+
default: throw new Error(`Unknown type: ${type}\nAvailable types: resource, controller, model, repository, schemas`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Generate a full resource
|
|
285
|
+
*/
|
|
286
|
+
async function generateResource(name, lowerName, resourcePath, templates, ext) {
|
|
287
|
+
console.log(`\nGenerating resource: ${name}...\n`);
|
|
288
|
+
if (!existsSync(resourcePath)) {
|
|
289
|
+
mkdirSync(resourcePath, { recursive: true });
|
|
290
|
+
console.log(` + Created: src/resources/${lowerName}/`);
|
|
291
|
+
}
|
|
292
|
+
const files = {
|
|
293
|
+
[`${lowerName}.model.${ext}`]: templates.model(name),
|
|
294
|
+
[`${lowerName}.repository.${ext}`]: templates.repository(name),
|
|
295
|
+
[`${lowerName}.resource.${ext}`]: templates.resource(name)
|
|
296
|
+
};
|
|
297
|
+
for (const [filename, content] of Object.entries(files)) {
|
|
298
|
+
const filepath = join(resourcePath, filename);
|
|
299
|
+
if (existsSync(filepath)) console.warn(` ! Skipped: ${filename} (already exists)`);
|
|
300
|
+
else {
|
|
301
|
+
writeFileSync(filepath, content);
|
|
302
|
+
console.log(` + Created: ${filename}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
const testsDir = join(process.cwd(), "tests");
|
|
306
|
+
if (!existsSync(testsDir)) mkdirSync(testsDir, { recursive: true });
|
|
307
|
+
const testPath = join(testsDir, `${lowerName}.test.${ext}`);
|
|
308
|
+
if (!existsSync(testPath)) {
|
|
309
|
+
writeFileSync(testPath, templates.test(name));
|
|
310
|
+
console.log(` + Created: tests/${lowerName}.test.${ext}`);
|
|
311
|
+
}
|
|
312
|
+
const isMultiTenant = readProjectConfig().tenant === "multi";
|
|
313
|
+
console.log(`
|
|
314
|
+
╔═══════════════════════════════════════════════════════════════╗
|
|
315
|
+
║ Resource Generated ║
|
|
316
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
317
|
+
|
|
318
|
+
Next steps:
|
|
319
|
+
|
|
320
|
+
1. Register in src/resources/index.${ext}:
|
|
321
|
+
import ${lowerName}Resource from './${lowerName}/${lowerName}.resource.js';
|
|
322
|
+
|
|
323
|
+
export const resources = [
|
|
324
|
+
// ... existing resources
|
|
325
|
+
${lowerName}Resource,
|
|
326
|
+
];
|
|
327
|
+
|
|
328
|
+
2. Customize the model schema in:
|
|
329
|
+
src/resources/${lowerName}/${lowerName}.model.${ext}
|
|
330
|
+
|
|
331
|
+
3. Adjust permissions in ${lowerName}.resource.${ext}:
|
|
332
|
+
${isMultiTenant ? ` - requireOrgMembership() → any org member
|
|
333
|
+
- requireOrgRole('admin') → specific org roles` : ` - requireAuth() → any authenticated user
|
|
334
|
+
- requireRoles(['admin']) → specific platform roles`}
|
|
335
|
+
|
|
336
|
+
4. Run tests:
|
|
337
|
+
npm test
|
|
338
|
+
`);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Generate a single file
|
|
342
|
+
*/
|
|
343
|
+
async function generateFile(name, lowerName, resourcePath, fileType, template, ext) {
|
|
344
|
+
console.log(`\nGenerating ${fileType}: ${name}...\n`);
|
|
345
|
+
if (!existsSync(resourcePath)) {
|
|
346
|
+
mkdirSync(resourcePath, { recursive: true });
|
|
347
|
+
console.log(` + Created: src/resources/${lowerName}/`);
|
|
348
|
+
}
|
|
349
|
+
const filename = `${lowerName}.${fileType}.${ext}`;
|
|
350
|
+
const filepath = join(resourcePath, filename);
|
|
351
|
+
if (existsSync(filepath)) throw new Error(`${filename} already exists. Remove it first or use a different name.`);
|
|
352
|
+
writeFileSync(filepath, template(name));
|
|
353
|
+
console.log(` + Created: ${filename}`);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
//#endregion
|
|
357
|
+
export { generate as default, generate };
|
|
358
|
+
//# sourceMappingURL=generate.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.mjs","names":[],"sources":["../../../src/cli/commands/generate.ts"],"sourcesContent":["/**\n * Arc CLI - Generate Command\n *\n * Scaffolds resources with consistent naming:\n * - src/resources/product/product.model.ts\n * - src/resources/product/product.repository.ts\n * - src/resources/product/product.resource.ts\n * - src/resources/product/product.controller.ts\n * - src/resources/product/product.schemas.ts\n */\n\nimport { writeFileSync, mkdirSync, existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { pluralize } from \"../utils/pluralize.js\";\n\ninterface ArcProjectConfig {\n adapter?: \"mongokit\" | \"custom\";\n auth?: \"jwt\" | \"better-auth\";\n tenant?: \"multi\" | \"single\";\n typescript?: boolean;\n}\n\n// Read .arcrc project config (written by `arc init`)\nfunction readProjectConfig(): ArcProjectConfig {\n try {\n const rcPath = join(process.cwd(), \".arcrc\");\n return JSON.parse(readFileSync(rcPath, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\n// Check if TypeScript project\nfunction isTypeScriptProject(): boolean {\n return existsSync(join(process.cwd(), \"tsconfig.json\"));\n}\n\n// Templates\nfunction getTemplates(ts: boolean, config: ArcProjectConfig = {}) {\n const isMultiTenant = config.tenant === \"multi\";\n\n return {\n model: (name: string) => `/**\n * ${name} Model\n * Generated by Arc CLI\n */\n\nimport mongoose${ts ? \", { type HydratedDocument }\" : \"\"} from 'mongoose';\n\nconst { Schema } = mongoose;\n${\n ts\n ? `\nexport interface I${name} {\n name: string;\n description?: string;\n isActive: boolean;\n}\n\nexport type ${name}Document = HydratedDocument<I${name}>;\n`\n : \"\"\n}\nconst ${name.toLowerCase()}Schema = new Schema${ts ? `<I${name}>` : \"\"}(\n {\n name: { type: String, required: true, trim: true },\n description: { type: String, trim: true },\n isActive: { type: Boolean, default: true },\n },\n { timestamps: true }\n);\n\n// Indexes\n${name.toLowerCase()}Schema.index({ name: 1 });\n${name.toLowerCase()}Schema.index({ isActive: 1 });\n\nconst ${name} = mongoose.models.${name} || mongoose.model('${name}', ${name.toLowerCase()}Schema);\nexport default ${name};\n`,\n\n repository: (name: string) => `/**\n * ${name} Repository\n * Generated by Arc CLI\n */\n\nimport {\n Repository,\n methodRegistryPlugin,\n softDeletePlugin,\n mongoOperationsPlugin,\n} from '@classytic/mongokit';\nimport ${name} from './${name.toLowerCase()}.model.js';\n\nclass ${name}Repository extends Repository {\n constructor() {\n super(${name}, [\n methodRegistryPlugin(),\n softDeletePlugin(),\n mongoOperationsPlugin(),\n ]);\n }\n\n /**\n * Find all active records\n */\n async findActive() {\n return this.Model.find({ isActive: true, deletedAt: null }).lean();\n }\n}\n\nconst ${name.toLowerCase()}Repository = new ${name}Repository();\nexport default ${name.toLowerCase()}Repository;\nexport { ${name}Repository };\n`,\n\n controller: (name: string) => `/**\n * ${name} Controller\n * Generated by Arc CLI\n *\n * Note: defineResource() auto-creates a controller from the adapter.\n * Only create a custom controller when you need custom methods.\n */\n\nimport { BaseController } from '@classytic/arc';\nimport ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';\n\nclass ${name}Controller extends BaseController {\n constructor() {\n super(${name.toLowerCase()}Repository, {\n resourceName: '${name.toLowerCase()}',\n });\n }\n\n // Add custom controller methods here\n}\n\nconst ${name.toLowerCase()}Controller = new ${name}Controller();\nexport default ${name.toLowerCase()}Controller;\n`,\n\n schemas: (name: string) => `/**\n * ${name} Schemas\n * Generated by Arc CLI\n */\n\nimport ${name} from './${name.toLowerCase()}.model.js';\nimport { buildCrudSchemasFromModel } from '@classytic/mongokit/utils';\n\n/**\n * CRUD Schemas with Field Rules\n */\nconst crudSchemas = buildCrudSchemasFromModel(${name}, {\n strictAdditionalProperties: true,\n fieldRules: {\n // Mark fields as system-managed (excluded from create/update)\n // deletedAt: { systemManaged: true },\n },\n query: {\n filterableFields: {\n isActive: 'boolean',\n createdAt: 'date',\n },\n },\n});\n\nexport default crudSchemas;\n`,\n\n resource: (name: string) => {\n const useMongoKit = config.adapter === \"mongokit\" || !config.adapter;\n const queryParserImport = useMongoKit\n ? `\\nimport { QueryParser } from '@classytic/mongokit';\\n\\nconst queryParser = new QueryParser();\\n`\n : \"\";\n const queryParserConfig = useMongoKit ? `\\n queryParser,` : \"\";\n\n return isMultiTenant\n ? `/**\n * ${name} Resource\n * Generated by Arc CLI\n */\n\nimport { defineResource, createMongooseAdapter } from '@classytic/arc';\nimport { requireOrgMembership, requireOrgRole } from '@classytic/arc/permissions';\nimport ${name}${ts ? `, { type I${name} }` : \"\"} from './${name.toLowerCase()}.model.js';\nimport ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';${queryParserImport}\n\nconst ${name.toLowerCase()}Resource = defineResource${ts ? `<I${name}>` : \"\"}({\n name: '${name.toLowerCase()}',\n adapter: createMongooseAdapter(${name}, ${name.toLowerCase()}Repository),${queryParserConfig}\n presets: ['softDelete'],\n permissions: {\n list: requireOrgMembership(),\n get: requireOrgMembership(),\n create: requireOrgRole('admin'),\n update: requireOrgRole('admin'),\n delete: requireOrgRole('admin'),\n },\n});\n\nexport default ${name.toLowerCase()}Resource;\n`\n : `/**\n * ${name} Resource\n * Generated by Arc CLI\n */\n\nimport { defineResource, createMongooseAdapter } from '@classytic/arc';\nimport { requireAuth, requireRoles } from '@classytic/arc/permissions';\nimport ${name}${ts ? `, { type I${name} }` : \"\"} from './${name.toLowerCase()}.model.js';\nimport ${name.toLowerCase()}Repository from './${name.toLowerCase()}.repository.js';${queryParserImport}\n\nconst ${name.toLowerCase()}Resource = defineResource${ts ? `<I${name}>` : \"\"}({\n name: '${name.toLowerCase()}',\n adapter: createMongooseAdapter(${name}, ${name.toLowerCase()}Repository),${queryParserConfig}\n presets: ['softDelete'],\n permissions: {\n list: requireAuth(),\n get: requireAuth(),\n create: requireRoles(['admin']),\n update: requireRoles(['admin']),\n delete: requireRoles(['admin']),\n },\n});\n\nexport default ${name.toLowerCase()}Resource;\n`;\n },\n\n test: (name: string) => `/**\n * ${name} Tests\n * Generated by Arc CLI\n */\n\nimport { describe, it, expect, beforeAll, afterAll } from 'vitest';\nimport mongoose from 'mongoose';\nimport { createMinimalTestApp } from '@classytic/arc/testing';\n${ts ? \"import type { FastifyInstance } from 'fastify';\\n\" : \"\"}import ${name.toLowerCase()}Resource from '../src/resources/${name.toLowerCase()}/${name.toLowerCase()}.resource.js';\n\ndescribe('${name} Resource', () => {\n let app${ts ? \": FastifyInstance\" : \"\"};\n\n beforeAll(async () => {\n const testDbUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/arc-app-test';\n await mongoose.connect(testDbUri);\n\n app = createMinimalTestApp();\n await app.register(${name.toLowerCase()}Resource.toPlugin());\n await app.ready();\n });\n\n afterAll(async () => {\n await app.close();\n await mongoose.connection.close();\n });\n\n describe('GET /${pluralize(name.toLowerCase())}', () => {\n it('should return a list', async () => {\n const response = await app.inject({\n method: 'GET',\n url: '/${pluralize(name.toLowerCase())}',\n });\n\n expect(response.statusCode).toBe(200);\n const body = JSON.parse(response.body);\n expect(body).toHaveProperty('docs');\n });\n });\n});\n`,\n };\n}\n\n/**\n * Generate command handler\n */\nexport async function generate(\n type: string | undefined,\n args: string[],\n): Promise<void> {\n if (!type) {\n throw new Error(\n \"Missing type argument\\nUsage: arc generate <resource|controller|model|repository|schemas> <name>\",\n );\n }\n\n const [name] = args;\n if (!name) {\n throw new Error(\n \"Missing name argument\\nUsage: arc generate <type> <name>\\nExample: arc generate resource product\",\n );\n }\n\n // Capitalize first letter\n const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);\n const lowerName = name.toLowerCase();\n\n // Detect project config\n const projectConfig = readProjectConfig();\n const ts = projectConfig.typescript ?? isTypeScriptProject();\n const ext = ts ? \"ts\" : \"js\";\n const templates = getTemplates(ts, projectConfig);\n\n // Resource path: src/resources/<name>/\n const resourcePath = join(process.cwd(), \"src\", \"resources\", lowerName);\n\n switch (type) {\n case \"resource\":\n case \"r\":\n await generateResource(\n capitalizedName,\n lowerName,\n resourcePath,\n templates,\n ext,\n );\n break;\n\n case \"controller\":\n case \"c\":\n await generateFile(\n capitalizedName,\n lowerName,\n resourcePath,\n \"controller\",\n templates.controller,\n ext,\n );\n break;\n\n case \"model\":\n case \"m\":\n await generateFile(\n capitalizedName,\n lowerName,\n resourcePath,\n \"model\",\n templates.model,\n ext,\n );\n break;\n\n case \"repository\":\n case \"repo\":\n await generateFile(\n capitalizedName,\n lowerName,\n resourcePath,\n \"repository\",\n templates.repository,\n ext,\n );\n break;\n\n case \"schemas\":\n case \"s\":\n await generateFile(\n capitalizedName,\n lowerName,\n resourcePath,\n \"schemas\",\n templates.schemas,\n ext,\n );\n break;\n\n default:\n throw new Error(\n `Unknown type: ${type}\\nAvailable types: resource, controller, model, repository, schemas`,\n );\n }\n}\n\n/**\n * Generate a full resource\n */\nasync function generateResource(\n name: string,\n lowerName: string,\n resourcePath: string,\n templates: ReturnType<typeof getTemplates>,\n ext: string,\n): Promise<void> {\n console.log(`\\nGenerating resource: ${name}...\\n`);\n\n // Create directory\n if (!existsSync(resourcePath)) {\n mkdirSync(resourcePath, { recursive: true });\n console.log(` + Created: src/resources/${lowerName}/`);\n }\n\n // Generate files (defineResource() auto-creates controller, no schemas needed)\n const files: Record<string, string> = {\n [`${lowerName}.model.${ext}`]: templates.model(name),\n [`${lowerName}.repository.${ext}`]: templates.repository(name),\n [`${lowerName}.resource.${ext}`]: templates.resource(name),\n };\n\n for (const [filename, content] of Object.entries(files)) {\n const filepath = join(resourcePath, filename);\n if (existsSync(filepath)) {\n console.warn(` ! Skipped: ${filename} (already exists)`);\n } else {\n writeFileSync(filepath, content);\n console.log(` + Created: ${filename}`);\n }\n }\n\n // Generate test file\n const testsDir = join(process.cwd(), \"tests\");\n if (!existsSync(testsDir)) {\n mkdirSync(testsDir, { recursive: true });\n }\n const testPath = join(testsDir, `${lowerName}.test.${ext}`);\n if (!existsSync(testPath)) {\n writeFileSync(testPath, templates.test(name));\n console.log(` + Created: tests/${lowerName}.test.${ext}`);\n }\n\n const isMultiTenant = readProjectConfig().tenant === \"multi\";\n\n console.log(`\n╔═══════════════════════════════════════════════════════════════╗\n║ Resource Generated ║\n╚═══════════════════════════════════════════════════════════════╝\n\nNext steps:\n\n1. Register in src/resources/index.${ext}:\n import ${lowerName}Resource from './${lowerName}/${lowerName}.resource.js';\n\n export const resources = [\n // ... existing resources\n ${lowerName}Resource,\n ];\n\n2. Customize the model schema in:\n src/resources/${lowerName}/${lowerName}.model.${ext}\n\n3. Adjust permissions in ${lowerName}.resource.${ext}:\n${\n isMultiTenant\n ? ` - requireOrgMembership() → any org member\n - requireOrgRole('admin') → specific org roles`\n : ` - requireAuth() → any authenticated user\n - requireRoles(['admin']) → specific platform roles`\n}\n\n4. Run tests:\n npm test\n`);\n}\n\n/**\n * Generate a single file\n */\nasync function generateFile(\n name: string,\n lowerName: string,\n resourcePath: string,\n fileType: string,\n template: (name: string) => string,\n ext: string,\n): Promise<void> {\n console.log(`\\nGenerating ${fileType}: ${name}...\\n`);\n\n if (!existsSync(resourcePath)) {\n mkdirSync(resourcePath, { recursive: true });\n console.log(` + Created: src/resources/${lowerName}/`);\n }\n\n const filename = `${lowerName}.${fileType}.${ext}`;\n const filepath = join(resourcePath, filename);\n\n if (existsSync(filepath)) {\n throw new Error(\n `${filename} already exists. Remove it first or use a different name.`,\n );\n }\n\n writeFileSync(filepath, template(name));\n console.log(` + Created: ${filename}`);\n}\n\nexport default generate;\n"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/cli/commands/init.d.ts
|
|
1
2
|
/**
|
|
2
3
|
* Arc CLI - Init Command
|
|
3
4
|
*
|
|
@@ -9,16 +10,19 @@
|
|
|
9
10
|
* Automatically installs dependencies using detected package manager.
|
|
10
11
|
*/
|
|
11
12
|
interface InitOptions {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
name?: string;
|
|
14
|
+
adapter?: "mongokit" | "custom";
|
|
15
|
+
auth?: "jwt" | "better-auth";
|
|
16
|
+
tenant?: "multi" | "single";
|
|
17
|
+
typescript?: boolean;
|
|
18
|
+
edge?: boolean;
|
|
19
|
+
skipInstall?: boolean;
|
|
20
|
+
force?: boolean;
|
|
18
21
|
}
|
|
19
22
|
/**
|
|
20
23
|
* Initialize a new Arc project
|
|
21
24
|
*/
|
|
22
25
|
declare function init(options?: InitOptions): Promise<void>;
|
|
23
|
-
|
|
24
|
-
export {
|
|
26
|
+
//#endregion
|
|
27
|
+
export { InitOptions, init as default, init };
|
|
28
|
+
//# sourceMappingURL=init.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.mts","names":[],"sources":["../../../src/cli/commands/init.ts"],"mappings":";;AAuBA;;;;;;;;;UAAiB,WAAA;EACf,IAAA;EACA,OAAA;EACA,IAAA;EACA,MAAA;EACA,UAAA;EACA,IAAA;EACA,WAAA;EACA,KAAA;AAAA;;;;iBAmBoB,IAAA,CAAK,OAAA,GAAS,WAAA,GAAmB,OAAA"}
|