···13131414 "github.com/bluesky-social/indigo/atproto/syntax"1515 "tangled.sh/tangled.sh/core/api/tangled"1616+ "tangled.sh/tangled.sh/core/consts"1617)17181819type ConcreteType string···7877 return vt.Type == ConcreteTypeBool7978}80798181-func (vt ValueType) IsEnumType() bool {8080+func (vt ValueType) IsEnum() bool {8281 return len(vt.Enum) > 08382}8483···97969897 Name string9998 ValueType ValueType100100- Scope syntax.NSID9999+ Scope []string101100 Color *string102101 Multiple bool103102 Created time.Time···114113 Color: l.Color,115114 CreatedAt: l.Created.Format(time.RFC3339),116115 Multiple: &l.Multiple,117117- Scope: l.Scope.String(),116116+ Scope: l.Scope,118117 ValueType: &vt,119118 }120119}···140139 return *ld.Color141140}142141143143-func LabelDefinitionFromRecord(did, rkey string, record tangled.LabelDefinition) LabelDefinition {142142+func LabelDefinitionFromRecord(did, rkey string, record tangled.LabelDefinition) (*LabelDefinition, error) {144143 created, err := time.Parse(time.RFC3339, record.CreatedAt)145144 if err != nil {146145 created = time.Now()···156155 vt = ValueTypeFromRecord(*record.ValueType)157156 }158157159159- return LabelDefinition{158158+ return &LabelDefinition{160159 Did: did,161160 Rkey: rkey,162161163162 Name: record.Name,164163 ValueType: vt,165165- Scope: syntax.NSID(record.Scope),164164+ Scope: record.Scope,166165 Color: record.Color,167166 Multiple: multiple,168167 Created: created,169169- }168168+ }, nil170169}171170172171func DeleteLabelDefinition(e Execer, filters ...filter) error {···185184 return err186185}187186187187+// no updating type for now188188func AddLabelDefinition(e Execer, l *LabelDefinition) (int64, error) {189189 result, err := e.Exec(190190 `insert into label_definitions (···212210 l.ValueType.Type,213211 l.ValueType.Format,214212 strings.Join(l.ValueType.Enum, ","),215215- l.Scope.String(),213213+ strings.Join(l.Scope, ","),216214 l.Color,217215 l.Multiple,218216 l.Created.Format(time.RFC3339),···276274277275 for rows.Next() {278276 var labelDefinition LabelDefinition279279- var createdAt, enumVariants string277277+ var createdAt, enumVariants, scopes string280278 var color sql.Null[string]281279 var multiple int282280···288286 &labelDefinition.ValueType.Type,289287 &labelDefinition.ValueType.Format,290288 &enumVariants,291291- &labelDefinition.Scope,289289+ &scopes,292290 &color,293291 &multiple,294292 &createdAt,···311309312310 if enumVariants != "" {313311 labelDefinition.ValueType.Enum = strings.Split(enumVariants, ",")312312+ }313313+314314+ for s := range strings.SplitSeq(scopes, ",") {315315+ labelDefinition.Scope = append(labelDefinition.Scope, s)314316 }315317316318 labelDefinitions = append(labelDefinitions, labelDefinition)···637631 return false638632}639633640640-func (s *LabelState) GetValSet(l string) set {641641- return s.inner[l]634634+// go maps behavior in templates make this necessary,635635+// indexing a map and getting `set` in return is apparently truthy636636+func (s LabelState) ContainsLabelAndVal(l, v string) bool {637637+ if valset, exists := s.inner[l]; exists {638638+ if _, exists := valset[v]; exists {639639+ return true640640+ }641641+ }642642+643643+ return false644644+}645645+646646+func (s LabelState) GetValSet(l string) set {647647+ if valset, exists := s.inner[l]; exists {648648+ return valset649649+ } else {650650+ return make(set)651651+ }642652}643653644654type LabelApplicationCtx struct {···680658}681659682660func (c *LabelApplicationCtx) ApplyLabelOp(state LabelState, op LabelOp) error {683683- def := c.Defs[op.OperandKey]661661+ def, ok := c.Defs[op.OperandKey]662662+ if !ok {663663+ // this def was deleted, but an op exists, so we just skip over the op664664+ return nil665665+ }684666685667 switch op.Operation {686668 case LabelOperationAdd:···744718 for _, o := range ops {745719 _ = c.ApplyLabelOp(state, o)746720 }721721+}722722+723723+// IsInverse checks if one label operation is the inverse of another724724+// returns true if one is an add and the other is a delete with the same key and value725725+func (op1 LabelOp) IsInverse(op2 LabelOp) bool {726726+ if op1.OperandKey != op2.OperandKey || op1.OperandValue != op2.OperandValue {727727+ return false728728+ }729729+730730+ return (op1.Operation == LabelOperationAdd && op2.Operation == LabelOperationDel) ||731731+ (op1.Operation == LabelOperationDel && op2.Operation == LabelOperationAdd)732732+}733733+734734+// removes pairs of label operations that are inverses of each other735735+// from the given slice. the function preserves the order of remaining operations.736736+func ReduceLabelOps(ops []LabelOp) []LabelOp {737737+ if len(ops) <= 1 {738738+ return ops739739+ }740740+741741+ keep := make([]bool, len(ops))742742+ for i := range keep {743743+ keep[i] = true744744+ }745745+746746+ for i := range ops {747747+ if !keep[i] {748748+ continue749749+ }750750+751751+ for j := i + 1; j < len(ops); j++ {752752+ if !keep[j] {753753+ continue754754+ }755755+756756+ if ops[i].IsInverse(ops[j]) {757757+ keep[i] = false758758+ keep[j] = false759759+ break // move to next i since this one is now eliminated760760+ }761761+ }762762+ }763763+764764+ // build result slice with only kept operations765765+ var result []LabelOp766766+ for i, op := range ops {767767+ if keep[i] {768768+ result = append(result, op)769769+ }770770+ }771771+772772+ return result773773+}774774+775775+func DefaultLabelDefs() []string {776776+ rkeys := []string{777777+ "wontfix",778778+ "duplicate",779779+ "assignee",780780+ "good-first-issue",781781+ "documentation",782782+ }783783+784784+ defs := make([]string, len(rkeys))785785+ for i, r := range rkeys {786786+ defs[i] = fmt.Sprintf("at://%s/%s/%s", consts.TangledDid, tangled.LabelDefinitionNSID, r)787787+ }788788+789789+ return defs747790}
+6-14
appview/oauth/handler/handler.go
···353353 return pubKey, nil354354}355355356356-var (357357- tangledDid = "did:plc:wshs7t2adsemcrrd4snkeqli"358358- icyDid = "did:plc:hwevmowznbiukdf6uk5dwrrq"359359-360360- defaultSpindle = "spindle.tangled.sh"361361- defaultKnot = "knot1.tangled.sh"362362-)363363-364356func (o *OAuthHandler) addToDefaultSpindle(did string) {365357 // use the tangled.sh app password to get an accessJwt366358 // and create an sh.tangled.spindle.member record with that···372380 }373381374382 log.Printf("adding %s to default spindle", did)375375- session, err := o.createAppPasswordSession(o.config.Core.AppPassword, tangledDid)383383+ session, err := o.createAppPasswordSession(o.config.Core.AppPassword, consts.TangledDid)376384 if err != nil {377385 log.Printf("failed to create session: %s", err)378386 return···381389 record := tangled.SpindleMember{382390 LexiconTypeID: "sh.tangled.spindle.member",383391 Subject: did,384384- Instance: defaultSpindle,392392+ Instance: consts.DefaultSpindle,385393 CreatedAt: time.Now().Format(time.RFC3339),386394 }387395···403411 return404412 }405413406406- if slices.Contains(allKnots, defaultKnot) {414414+ if slices.Contains(allKnots, consts.DefaultKnot) {407415 log.Printf("did %s is already a member of the default knot", did)408416 return409417 }410418411419 log.Printf("adding %s to default knot", did)412412- session, err := o.createAppPasswordSession(o.config.Core.TmpAltAppPassword, icyDid)420420+ session, err := o.createAppPasswordSession(o.config.Core.TmpAltAppPassword, consts.IcyDid)413421 if err != nil {414422 log.Printf("failed to create session: %s", err)415423 return···418426 record := tangled.KnotMember{419427 LexiconTypeID: "sh.tangled.knot.member",420428 Subject: did,421421- Domain: defaultKnot,429429+ Domain: consts.DefaultKnot,422430 CreatedAt: time.Now().Format(time.RFC3339),423431 }424432···427435 return428436 }429437430430- if err := o.enforcer.AddKnotMember(defaultKnot, did); err != nil {438438+ if err := o.enforcer.AddKnotMember(consts.DefaultKnot, did); err != nil {431439 log.Printf("failed to set up enforcer rules: %s", err)432440 return433441 }